]> gitweb.ps.run Git - matrix_esp_thesis/commitdiff
changes to olm and esp
authorPatrick <patrick.schoenberger@posteo.de>
Mon, 13 Nov 2023 21:33:49 +0000 (22:33 +0100)
committerPatrick <patrick.schoenberger@posteo.de>
Mon, 13 Nov 2023 21:33:49 +0000 (22:33 +0100)
esp32/esp_project/components/matrix/CMakeLists.txt
esp32/esp_project/main/SendEncrypted.c
esp32/esp_project/main/Verify.c
ext/olm/include/olm/olm_export.h
ext/olm/include/olm/session.hh
ext/olm/lib/crypto-algorithms/aes.h
ext/olm/lib/crypto-algorithms/aes_test.c
src/matrix_http_esp32.c

index 23879485fbc3f7a6e516f5e0b0f3928bc6ca2f2e..bf7da7a9ef289368dae2fc7840d5ae9556866109 100644 (file)
@@ -1,16 +1,16 @@
-idf_component_register(SRCS
-                            "../../../../src/matrix.c"
-                            "../../../../src/matrix_http_esp32.c"
-                            "../../../../ext/mjson/src/mjson.c"
-                       INCLUDE_DIRS
-                            "../../../../ext/olm/include"
-                            "../../../../ext/olm/lib"
-                            "../../../../ext/mjson/src"
-                            "../../../../src"
-                       REQUIRES
-                            esp-tls
-                            esp_http_client
-                            esp_netif
-                            nvs_flash)
-
-SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -fpermissive")
+idf_component_register(SRCS\r
+                            "../../../../src/matrix.c"\r
+                            "../../../../src/matrix_http_esp32.c"\r
+                            "../../../../ext/mjson/src/mjson.c"\r
+                       INCLUDE_DIRS\r
+                            "../../../../ext/olm/include"\r
+                            "../../../../ext/olm/lib"\r
+                            "../../../../ext/mjson/src"\r
+                            "../../../../src"\r
+                       REQUIRES\r
+                            esp-tls\r
+                            esp_http_client\r
+                            esp_netif\r
+                            nvs_flash)\r
+\r
+SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -fpermissive")\r
index 8d813adff96e134109516efe1cf11ca6013de3b2..11e9e0d4c8b445e801d8f8d405e451e4f89dd8f3 100644 (file)
@@ -1,65 +1,65 @@
-#define OLMLIB_VERSION_MAJOR 3
-#define OLMLIB_VERSION_MINOR 2
-#define OLMLIB_VERSION_PATCH 15
-
-#define OLM_STATIC_DEFINE
-
-#include <stdio.h>
-#include <matrix.h>
-
-#define SERVER       "https://matrix.org"
-#define USER_ID      "@pscho:matrix.org"
-#define ROOM_ID      "!XKFUjAsGrSSrpDFIxB:matrix.org"
-
-int
-main(void)
-{
-    MatrixClient client;
-    MatrixClientInit(&client);
-    
-    MatrixHttpInit(&client.hc, SERVER);
-
-    MatrixClientSetUserId(&client, USER_ID);
-
-    MatrixClientLoginPassword(&client,
-        "pscho",
-        "Wc23EbmB9G3faMq",
-        "Test1");
-
-    MatrixClientUploadDeviceKeys(&client);
-    MatrixClientGenerateOnetimeKeys(&client, 10);
-    MatrixClientUploadOnetimeKeys(&client);
-
-    // create megolmsession
-    MatrixMegolmOutSession * megolmOutSession;
-    MatrixClientNewMegolmOutSession(&client,
-        ROOM_ID,
-        &megolmOutSession);
-    printf("megolm session id: %.10s... key: %.10s...\n", megolmOutSession->id, megolmOutSession->key);
-
-    MatrixClientShareMegolmOutSession(&client,
-        USER_ID,
-        "ULZZOKJBYN",
-        megolmOutSession);
-
-    MatrixClientSendEventEncrypted(&client,
-        ROOM_ID,
-        "m.room.message",
-        "{\"body\":\"Hello\",\"msgtype\":\"m.text\"}");
-    
-    MatrixClientDeleteDevice(&client);
-
-    MatrixHttpDeinit(&client.hc);
-
-    return 0;
-}
-
-#include "wifi.h"
-
-void
-app_main(void)
-{
-    wifi_init("Hundehuette", "Affensicherespw55");
-
-    main();
-}
+#define OLMLIB_VERSION_MAJOR 3\r
+#define OLMLIB_VERSION_MINOR 2\r
+#define OLMLIB_VERSION_PATCH 15\r
+\r
+#define OLM_STATIC_DEFINE\r
+\r
+#include <stdio.h>\r
+#include <matrix.h>\r
+\r
+#define SERVER       "https://matrix.org"\r
+#define USER_ID      "@pscho:matrix.org"\r
+#define ROOM_ID      "!XKFUjAsGrSSrpDFIxB:matrix.org"\r
+\r
+int\r
+main(void)\r
+{\r
+    MatrixClient client;\r
+    MatrixClientInit(&client);\r
+    \r
+    MatrixHttpInit(&client.hc, SERVER);\r
+\r
+    MatrixClientSetUserId(&client, USER_ID);\r
+\r
+    MatrixClientLoginPassword(&client,\r
+        "pscho",\r
+        "Wc23EbmB9G3faMq",\r
+        "Test1");\r
+\r
+    MatrixClientUploadDeviceKeys(&client);\r
+    MatrixClientGenerateOnetimeKeys(&client, 10);\r
+    MatrixClientUploadOnetimeKeys(&client);\r
+\r
+    // create megolmsession\r
+    MatrixMegolmOutSession * megolmOutSession;\r
+    MatrixClientNewMegolmOutSession(&client,\r
+        ROOM_ID,\r
+        &megolmOutSession);\r
+    printf("megolm session id: %.10s... key: %.10s...\n", megolmOutSession->id, megolmOutSession->key);\r
+\r
+    MatrixClientShareMegolmOutSession(&client,\r
+        USER_ID,\r
+        "ULZZOKJBYN",\r
+        megolmOutSession);\r
+\r
+    MatrixClientSendEventEncrypted(&client,\r
+        ROOM_ID,\r
+        "m.room.message",\r
+        "{\"body\":\"Hello\",\"msgtype\":\"m.text\"}");\r
+    \r
+    MatrixClientDeleteDevice(&client);\r
+\r
+    MatrixHttpDeinit(&client.hc);\r
+\r
+    return 0;\r
+}\r
+\r
+#include "wifi.h"\r
+\r
+void\r
+app_main(void)\r
+{\r
+    wifi_init("Hundehuette", "Affensicherespw55");\r
+\r
+    main();\r
+}\r
index 91f9be85845e2c928cb450cd61eef6c01ff748d0..cda57097befcafd2cb869d271b0300de0a8c8d71 100644 (file)
-#include <matrix.h>
-#include <mjson.h>
-#include <olm/sas.h>
-
-#if !CONFIG_IDF_TARGET_LINUX
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "esp_system.h"
-#include "driver/gpio.h"
-#endif
-
-#include <stdio.h>
-
-#define SERVER       "https://matrix.org"
-#define USER_ID      "@pscho:matrix.org"
-
-#define DEVICE_ID    "ULZZOKJBYN"
-#define SENDER_KEY   "cjP41XzRlY+pd8DoiBuKQJj9o15mrx6gkrpqTkAPZ2c"
-#define ROOM_ID      "!XKFUjAsGrSSrpDFIxB:matrix.org"
-#define EVENT_ID     "$vOS09eUaI0CduqAcaIU5ZVk6ljLQfLspz7UThP8vaUM"
-#define SESSION_ID   "90UbGLue3ADVhvW7hFjoA2c6yg0JJKs/lPdMDZXnZAk"
-
-// main stack size: 3584
-
-#define STATIC static
-
-
-
-int
-main(void)
-{
-    MatrixClient * client = (MatrixClient*)malloc(sizeof(MatrixClient));
-    MatrixClientInit(client);
-
-    MatrixHttpInit(&client->hc, SERVER);
-    MatrixClientSetUserId(client, USER_ID);
-
-    MatrixClientLoginPassword(client,
-        "pscho",
-        "Wc23EbmB9G3faMq",
-        "Test1");
-    printf("deviceId: %s\n", client->deviceId);
-    MatrixClientGenerateOnetimeKeys(client, 10);
-    MatrixClientUploadOnetimeKeys(client);
-    MatrixClientUploadDeviceKeys(client);
-
-    STATIC char eventBuffer[1024];
-    MatrixClientGetRoomEvent(client,
-        ROOM_ID,
-        EVENT_ID,
-        eventBuffer, 1024);
-    printf("event: %s\n", eventBuffer);
-
-    #define SYNC_BUFFER_SIZE 1024*10
-
-    // char * syncBuffer = (char*)malloc(SYNC_BUFFER_SIZE);
-    STATIC char syncBuffer[SYNC_BUFFER_SIZE];
-    STATIC char nextBatch[1024];
-
-    while (! client->verified) {
-        MatrixClientSync(client, syncBuffer, SYNC_BUFFER_SIZE, nextBatch, 1024);
-    }
-
-    printf("verified!\n");
-
-    // create and share megolm out session
-    MatrixMegolmOutSession * megolmOutSession;
-    MatrixClientNewMegolmOutSession(client,
-        ROOM_ID,
-        &megolmOutSession);
-    printf("megolm session id: %.10s... key: %.10s...\n", megolmOutSession->id, megolmOutSession->key);
-    MatrixClientShareMegolmOutSession(client,
-        USER_ID,
-        "ULZZOKJBYN",
-        megolmOutSession);
-
-    // send 10 random messages
-    for (int i = 0; i < 10; i++) {
-        static const char * msgs[] = { "A", "B", "C" };
-        static char msg[128];
-        snprintf(msg, 128, "{\"body\":\"%s\",\"msgtype\":\"m.text\"}", msgs[rand()%(sizeof(msgs)/sizeof(msgs[0]))]);
-
-        MatrixClientSendEventEncrypted(client,
-            ROOM_ID,
-            "m.room.message",
-            msg);
-    }
-
-    MatrixClientDeleteDevice(client);
-        
-    MatrixHttpDeinit(&client->hc);
-
-    return 0;
-}
-
-#include "wifi.h"
-#include <esp_netif.h>
-
-void
-app_main(void)
-{
-    // wifi_init("Pixel_7762", "affeaffe");
-    // wifi_init("Hundehuette", "Affensicherespw55");
-    wifi_init("test", "/O801i25");
-
-    esp_netif_ip_info_t ip_info;
-    esp_netif_get_ip_info(IP_EVENT_STA_GOT_IP,&ip_info);
-    printf("My IP: " IPSTR "\n", IP2STR(&ip_info.ip));
-    printf("My GW: " IPSTR "\n", IP2STR(&ip_info.gw));
-    printf("My NETMASK: " IPSTR "\n", IP2STR(&ip_info.netmask));
-
-    // uint64_t bitmask = 0xffffffffffffffff;
-    // bitmask = bitmask & SOC_GPIO_VALID_GPIO_MASK;
-    // gpio_dump_io_configuration(stdout, bitmask);
-    gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);
-    // gpio_dump_io_configuration(stdout, bitmask);
-
-    main();
-}
+#include <matrix.h>\r
+#include <mjson.h>\r
+#include <olm/sas.h>\r
+\r
+#if !CONFIG_IDF_TARGET_LINUX\r
+#include "freertos/FreeRTOS.h"\r
+#include "freertos/task.h"\r
+#include "esp_system.h"\r
+#include "driver/gpio.h"\r
+#endif\r
+\r
+#include <stdio.h>\r
+\r
+#define SERVER       "https://matrix.org"\r
+#define USER_ID      "@pscho:matrix.org"\r
+\r
+#define DEVICE_ID    "ULZZOKJBYN"\r
+#define SENDER_KEY   "cjP41XzRlY+pd8DoiBuKQJj9o15mrx6gkrpqTkAPZ2c"\r
+#define ROOM_ID      "!XKFUjAsGrSSrpDFIxB:matrix.org"\r
+#define EVENT_ID     "$vOS09eUaI0CduqAcaIU5ZVk6ljLQfLspz7UThP8vaUM"\r
+#define SESSION_ID   "90UbGLue3ADVhvW7hFjoA2c6yg0JJKs/lPdMDZXnZAk"\r
+\r
+// main stack size: 3584\r
+\r
+#define STATIC static\r
+\r
+\r
+\r
+int\r
+main(void)\r
+{\r
+    MatrixClient * client = (MatrixClient*)malloc(sizeof(MatrixClient));\r
+    MatrixClientInit(client);\r
+\r
+    MatrixHttpInit(&client->hc, SERVER);\r
+    MatrixClientSetUserId(client, USER_ID);\r
+\r
+    MatrixClientLoginPassword(client,\r
+        "pscho",\r
+        "Wc23EbmB9G3faMq",\r
+        "Test1");\r
+    printf("deviceId: %s\n", client->deviceId);\r
+    MatrixClientGenerateOnetimeKeys(client, 10);\r
+    MatrixClientUploadOnetimeKeys(client);\r
+    MatrixClientUploadDeviceKeys(client);\r
+\r
+    STATIC char eventBuffer[1024];\r
+    MatrixClientGetRoomEvent(client,\r
+        ROOM_ID,\r
+        EVENT_ID,\r
+        eventBuffer, 1024);\r
+    printf("event: %s\n", eventBuffer);\r
+\r
+    #define SYNC_BUFFER_SIZE 1024*10\r
+\r
+    // char * syncBuffer = (char*)malloc(SYNC_BUFFER_SIZE);\r
+    STATIC char syncBuffer[SYNC_BUFFER_SIZE];\r
+    STATIC char nextBatch[1024];\r
+\r
+    while (! client->verified) {\r
+        MatrixClientSync(client, syncBuffer, SYNC_BUFFER_SIZE, nextBatch, 1024);\r
+    }\r
+\r
+    printf("verified!\n");\r
+\r
+    // create and share megolm out session\r
+    MatrixMegolmOutSession * megolmOutSession;\r
+    MatrixClientNewMegolmOutSession(client,\r
+        ROOM_ID,\r
+        &megolmOutSession);\r
+    printf("megolm session id: %.10s... key: %.10s...\n", megolmOutSession->id, megolmOutSession->key);\r
+    MatrixClientShareMegolmOutSession(client,\r
+        USER_ID,\r
+        "ULZZOKJBYN",\r
+        megolmOutSession);\r
+\r
+    // send 10 random messages\r
+    for (int i = 0; i < 10; i++) {\r
+        static const char * msgs[] = { "A", "B", "C" };\r
+        static char msg[128];\r
+        snprintf(msg, 128, "{\"body\":\"%s\",\"msgtype\":\"m.text\"}", msgs[rand()%(sizeof(msgs)/sizeof(msgs[0]))]);\r
+\r
+        MatrixClientSendEventEncrypted(client,\r
+            ROOM_ID,\r
+            "m.room.message",\r
+            msg);\r
+    }\r
+\r
+    MatrixClientDeleteDevice(client);\r
+        \r
+    MatrixHttpDeinit(&client->hc);\r
+\r
+    return 0;\r
+}\r
+\r
+#include "wifi.h"\r
+#include <esp_netif.h>\r
+\r
+void\r
+app_main(void)\r
+{\r
+    // wifi_init("Pixel_7762", "affeaffe");\r
+    // wifi_init("Hundehuette", "Affensicherespw55");\r
+    wifi_init("test", "/O801i25");\r
+\r
+    esp_netif_ip_info_t ip_info;\r
+    esp_netif_get_ip_info(IP_EVENT_STA_GOT_IP,&ip_info);\r
+    printf("My IP: " IPSTR "\n", IP2STR(&ip_info.ip));\r
+    printf("My GW: " IPSTR "\n", IP2STR(&ip_info.gw));\r
+    printf("My NETMASK: " IPSTR "\n", IP2STR(&ip_info.netmask));\r
+\r
+    // uint64_t bitmask = 0xffffffffffffffff;\r
+    // bitmask = bitmask & SOC_GPIO_VALID_GPIO_MASK;\r
+    // gpio_dump_io_configuration(stdout, bitmask);\r
+    gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);\r
+    // gpio_dump_io_configuration(stdout, bitmask);\r
+\r
+    main();\r
+}\r
index d7197a2433a6533049b42eed9570af381d1ea105..e3daaebf58b1ca3a7d3307eccd4fedb640a13632 100644 (file)
@@ -1,42 +1,42 @@
-
-#ifndef OLM_EXPORT_H
-#define OLM_EXPORT_H
-
-#ifdef OLM_STATIC_DEFINE
-#  define OLM_EXPORT
-#  define OLM_NO_EXPORT
-#else
-#  ifndef OLM_EXPORT
-#    ifdef olm_EXPORTS
-        /* We are building this library */
-#      define OLM_EXPORT 
-#    else
-        /* We are using this library */
-#      define OLM_EXPORT 
-#    endif
-#  endif
-
-#  ifndef OLM_NO_EXPORT
-#    define OLM_NO_EXPORT 
-#  endif
-#endif
-
-#ifndef OLM_DEPRECATED
-#  define OLM_DEPRECATED __attribute__ ((__deprecated__))
-#endif
-
-#ifndef OLM_DEPRECATED_EXPORT
-#  define OLM_DEPRECATED_EXPORT OLM_EXPORT OLM_DEPRECATED
-#endif
-
-#ifndef OLM_DEPRECATED_NO_EXPORT
-#  define OLM_DEPRECATED_NO_EXPORT OLM_NO_EXPORT OLM_DEPRECATED
-#endif
-
-#if 0 /* DEFINE_NO_DEPRECATED */
-#  ifndef OLM_NO_DEPRECATED
-#    define OLM_NO_DEPRECATED
-#  endif
-#endif
-
-#endif /* OLM_EXPORT_H */
+\r
+#ifndef OLM_EXPORT_H\r
+#define OLM_EXPORT_H\r
+\r
+#ifdef OLM_STATIC_DEFINE\r
+#  define OLM_EXPORT\r
+#  define OLM_NO_EXPORT\r
+#else\r
+#  ifndef OLM_EXPORT\r
+#    ifdef olm_EXPORTS\r
+        /* We are building this library */\r
+#      define OLM_EXPORT \r
+#    else\r
+        /* We are using this library */\r
+#      define OLM_EXPORT \r
+#    endif\r
+#  endif\r
+\r
+#  ifndef OLM_NO_EXPORT\r
+#    define OLM_NO_EXPORT \r
+#  endif\r
+#endif\r
+\r
+#ifndef OLM_DEPRECATED\r
+#  define OLM_DEPRECATED __attribute__ ((__deprecated__))\r
+#endif\r
+\r
+#ifndef OLM_DEPRECATED_EXPORT\r
+#  define OLM_DEPRECATED_EXPORT OLM_EXPORT OLM_DEPRECATED\r
+#endif\r
+\r
+#ifndef OLM_DEPRECATED_NO_EXPORT\r
+#  define OLM_DEPRECATED_NO_EXPORT OLM_NO_EXPORT OLM_DEPRECATED\r
+#endif\r
+\r
+#if 0 /* DEFINE_NO_DEPRECATED */\r
+#  ifndef OLM_NO_DEPRECATED\r
+#    define OLM_NO_DEPRECATED\r
+#  endif\r
+#endif\r
+\r
+#endif /* OLM_EXPORT_H */\r
index 41300dbea76dbe183a9d7c9f238eec94085930ca..a5d6f3ef51251f0d29613efafb49b13db5ecc776 100644 (file)
-/* Copyright 2015 OpenMarket Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef OLM_SESSION_HH_
-#define OLM_SESSION_HH_
-
-#include "olm/ratchet.hh"
-
-// Note: exports in this file are only for unit tests.  Nobody else should be
-// using this externally
-#include "olm/olm_export.h"
-
-namespace olm {
-
-struct Account;
-
-enum struct MessageType {
-    PRE_KEY = 0,
-    MESSAGE = 1,
-};
-
-struct OLM_EXPORT Session {
-
-    Session();
-
-    Ratchet ratchet;
-    OlmErrorCode last_error;
-
-    bool received_message;
-
-    _olm_curve25519_public_key alice_identity_key;
-    _olm_curve25519_public_key alice_base_key;
-    _olm_curve25519_public_key bob_one_time_key;
-
-    /** The number of random bytes that are needed to create a new outbound
-     * session. This will be 64 bytes since two ephemeral keys are needed. */
-    std::size_t new_outbound_session_random_length() const;
-
-    /** Start a new outbound session. Returns std::size_t(-1) on failure. On
-     * failure last_error will be set with an error code. The last_error will be
-     * NOT_ENOUGH_RANDOM if the number of random bytes was too small. */
-    std::size_t new_outbound_session(
-        Account const & local_account,
-        _olm_curve25519_public_key const & identity_key,
-        _olm_curve25519_public_key const & one_time_key,
-        std::uint8_t const * random, std::size_t random_length
-    );
-
-    /** Start a new inbound session from a pre-key message.
-     * Returns std::size_t(-1) on failure. On failure last_error will be set
-     * with an error code. The last_error will be BAD_MESSAGE_FORMAT if
-     * the message headers could not be decoded. */
-    std::size_t new_inbound_session(
-        Account & local_account,
-        _olm_curve25519_public_key const * their_identity_key,
-        std::uint8_t const * pre_key_message, std::size_t message_length
-    );
-
-    /** The number of bytes written by session_id() */
-    std::size_t session_id_length() const;
-
-    /** An identifier for this session. Generated by hashing the public keys
-     * used to create the session. Returns the length of the session id on
-     * success or std::size_t(-1) on failure. On failure last_error will be set
-     * with an error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if
-     * the id buffer was too small. */
-    std::size_t session_id(
-        std::uint8_t * id, std::size_t id_length
-    );
-
-    /** True if this session can be used to decode an inbound pre-key message.
-     * This can be used to test whether a pre-key message should be decoded
-     * with an existing session or if a new session will need to be created.
-     * Returns true if the session is the same. Returns false if either the
-     * session does not match or the pre-key message could not be decoded.
-     */
-    bool matches_inbound_session(
-        _olm_curve25519_public_key const * their_identity_key,
-        std::uint8_t const * pre_key_message, std::size_t message_length
-    ) const;
-
-    /** Whether the next message will be a pre-key message or a normal message.
-     * An outbound session will send pre-key messages until it receives a
-     * message with a ratchet key. */
-    MessageType encrypt_message_type() const;
-
-    std::size_t encrypt_message_length(
-        std::size_t plaintext_length
-    ) const;
-
-    /** The number of bytes of random data the encrypt method will need to
-     * encrypt a message. This will be 32 bytes if the session needs to
-     * generate a new ephemeral key, or will be 0 bytes otherwise. */
-    std::size_t encrypt_random_length() const;
-
-    /** Encrypt some plain-text. Returns the length of the encrypted message
-      * or std::size_t(-1) on failure. On failure last_error will be set with
-      * an error code. The last_error will be NOT_ENOUGH_RANDOM if the number
-      * of random bytes is too small. The last_error will be
-      * OUTPUT_BUFFER_TOO_SMALL if the output buffer is too small. */
-    std::size_t encrypt(
-        std::uint8_t const * plaintext, std::size_t plaintext_length,
-        std::uint8_t const * random, std::size_t random_length,
-        std::uint8_t * message, std::size_t message_length
-    );
-
-    /** An upper bound on the number of bytes of plain-text the decrypt method
-     * will write for a given input message length. */
-    std::size_t decrypt_max_plaintext_length(
-        MessageType message_type,
-        std::uint8_t const * message, std::size_t message_length
-    );
-
-    /** Decrypt a message. Returns the length of the decrypted plain-text or
-     * std::size_t(-1) on failure. On failure last_error will be set with an
-     * error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the
-     * plain-text buffer is too small. The last_error will be
-     * BAD_MESSAGE_VERSION if the message was encrypted with an unsupported
-     * version of the protocol. The last_error will be BAD_MESSAGE_FORMAT if
-     * the message headers could not be decoded. The last_error will be
-     * BAD_MESSAGE_MAC if the message could not be verified */
-    std::size_t decrypt(
-        MessageType message_type,
-        std::uint8_t const * message, std::size_t message_length,
-        std::uint8_t * plaintext, std::size_t max_plaintext_length
-    );
-
-    /**
-     * Write a string describing this session and its state (not including the
-     * private key) into the buffer provided.
-     *
-     * Takes a buffer to write to and the length of that buffer
-     */
-    void describe(char *buf, size_t buflen);
-};
-
-
-std::size_t pickle_length(
-    Session const & value
-);
-
-
-std::uint8_t * pickle(
-    std::uint8_t * pos,
-    Session const & value
-);
-
-
-OLM_EXPORT std::uint8_t const * unpickle(
-    std::uint8_t const * pos, std::uint8_t const * end,
-    Session & value
-);
-
-
-} // namespace olm
-
-#endif /* OLM_SESSION_HH_ */
+/* Copyright 2015 OpenMarket Ltd\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+#ifndef OLM_SESSION_HH_\r
+#define OLM_SESSION_HH_\r
+\r
+#include "olm/ratchet.hh"\r
+\r
+// Note: exports in this file are only for unit tests.  Nobody else should be\r
+// using this externally\r
+#include "olm/olm_export.h"\r
+\r
+namespace olm {\r
+\r
+struct Account;\r
+\r
+enum struct MessageType {\r
+    PRE_KEY = 0,\r
+    MESSAGE = 1,\r
+};\r
+\r
+struct OLM_EXPORT Session {\r
+\r
+    Session();\r
+\r
+    Ratchet ratchet;\r
+    OlmErrorCode last_error;\r
+\r
+    bool received_message;\r
+\r
+    _olm_curve25519_public_key alice_identity_key;\r
+    _olm_curve25519_public_key alice_base_key;\r
+    _olm_curve25519_public_key bob_one_time_key;\r
+\r
+    /** The number of random bytes that are needed to create a new outbound\r
+     * session. This will be 64 bytes since two ephemeral keys are needed. */\r
+    std::size_t new_outbound_session_random_length() const;\r
+\r
+    /** Start a new outbound session. Returns std::size_t(-1) on failure. On\r
+     * failure last_error will be set with an error code. The last_error will be\r
+     * NOT_ENOUGH_RANDOM if the number of random bytes was too small. */\r
+    std::size_t new_outbound_session(\r
+        Account const & local_account,\r
+        _olm_curve25519_public_key const & identity_key,\r
+        _olm_curve25519_public_key const & one_time_key,\r
+        std::uint8_t const * random, std::size_t random_length\r
+    );\r
+\r
+    /** Start a new inbound session from a pre-key message.\r
+     * Returns std::size_t(-1) on failure. On failure last_error will be set\r
+     * with an error code. The last_error will be BAD_MESSAGE_FORMAT if\r
+     * the message headers could not be decoded. */\r
+    std::size_t new_inbound_session(\r
+        Account & local_account,\r
+        _olm_curve25519_public_key const * their_identity_key,\r
+        std::uint8_t const * pre_key_message, std::size_t message_length\r
+    );\r
+\r
+    /** The number of bytes written by session_id() */\r
+    std::size_t session_id_length() const;\r
+\r
+    /** An identifier for this session. Generated by hashing the public keys\r
+     * used to create the session. Returns the length of the session id on\r
+     * success or std::size_t(-1) on failure. On failure last_error will be set\r
+     * with an error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if\r
+     * the id buffer was too small. */\r
+    std::size_t session_id(\r
+        std::uint8_t * id, std::size_t id_length\r
+    );\r
+\r
+    /** True if this session can be used to decode an inbound pre-key message.\r
+     * This can be used to test whether a pre-key message should be decoded\r
+     * with an existing session or if a new session will need to be created.\r
+     * Returns true if the session is the same. Returns false if either the\r
+     * session does not match or the pre-key message could not be decoded.\r
+     */\r
+    bool matches_inbound_session(\r
+        _olm_curve25519_public_key const * their_identity_key,\r
+        std::uint8_t const * pre_key_message, std::size_t message_length\r
+    ) const;\r
+\r
+    /** Whether the next message will be a pre-key message or a normal message.\r
+     * An outbound session will send pre-key messages until it receives a\r
+     * message with a ratchet key. */\r
+    MessageType encrypt_message_type() const;\r
+\r
+    std::size_t encrypt_message_length(\r
+        std::size_t plaintext_length\r
+    ) const;\r
+\r
+    /** The number of bytes of random data the encrypt method will need to\r
+     * encrypt a message. This will be 32 bytes if the session needs to\r
+     * generate a new ephemeral key, or will be 0 bytes otherwise. */\r
+    std::size_t encrypt_random_length() const;\r
+\r
+    /** Encrypt some plain-text. Returns the length of the encrypted message\r
+      * or std::size_t(-1) on failure. On failure last_error will be set with\r
+      * an error code. The last_error will be NOT_ENOUGH_RANDOM if the number\r
+      * of random bytes is too small. The last_error will be\r
+      * OUTPUT_BUFFER_TOO_SMALL if the output buffer is too small. */\r
+    std::size_t encrypt(\r
+        std::uint8_t const * plaintext, std::size_t plaintext_length,\r
+        std::uint8_t const * random, std::size_t random_length,\r
+        std::uint8_t * message, std::size_t message_length\r
+    );\r
+\r
+    /** An upper bound on the number of bytes of plain-text the decrypt method\r
+     * will write for a given input message length. */\r
+    std::size_t decrypt_max_plaintext_length(\r
+        MessageType message_type,\r
+        std::uint8_t const * message, std::size_t message_length\r
+    );\r
+\r
+    /** Decrypt a message. Returns the length of the decrypted plain-text or\r
+     * std::size_t(-1) on failure. On failure last_error will be set with an\r
+     * error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the\r
+     * plain-text buffer is too small. The last_error will be\r
+     * BAD_MESSAGE_VERSION if the message was encrypted with an unsupported\r
+     * version of the protocol. The last_error will be BAD_MESSAGE_FORMAT if\r
+     * the message headers could not be decoded. The last_error will be\r
+     * BAD_MESSAGE_MAC if the message could not be verified */\r
+    std::size_t decrypt(\r
+        MessageType message_type,\r
+        std::uint8_t const * message, std::size_t message_length,\r
+        std::uint8_t * plaintext, std::size_t max_plaintext_length\r
+    );\r
+\r
+    /**\r
+     * Write a string describing this session and its state (not including the\r
+     * private key) into the buffer provided.\r
+     *\r
+     * Takes a buffer to write to and the length of that buffer\r
+     */\r
+    void describe(char *buf, size_t buflen);\r
+};\r
+\r
+\r
+std::size_t pickle_length(\r
+    Session const & value\r
+);\r
+\r
+\r
+std::uint8_t * pickle(\r
+    std::uint8_t * pos,\r
+    Session const & value\r
+);\r
+\r
+\r
+OLM_EXPORT std::uint8_t const * unpickle(\r
+    std::uint8_t const * pos, std::uint8_t const * end,\r
+    Session & value\r
+);\r
+\r
+\r
+} // namespace olm\r
+\r
+#endif /* OLM_SESSION_HH_ */\r
index 84e53550fe1e9afcd3c54a7b332022db16f2d431..6d570f45e64c786d2a6354d003268101a5bb96b5 100644 (file)
-/*********************************************************************
-* Filename:   aes.h
-* Author:     Brad Conte (brad AT bradconte.com)
-* Copyright:
-* Disclaimer: This code is presented "as is" without any guarantees.
-* Details:    Defines the API for the corresponding AES implementation.
-*********************************************************************/
-
-#ifndef AES_H
-#define AES_H
-
-/*************************** HEADER FILES ***************************/
-#include <stddef.h>
-
-/****************************** MACROS ******************************/
-#define AES_BLOCK_SIZE 16               // AES operates on 16 bytes at a time
-
-/**************************** DATA TYPES ****************************/
-typedef unsigned char BYTE;            // 8-bit byte
-typedef unsigned int WORD;             // 32-bit word, change to "long" for 16-bit machines
-
-/*********************** FUNCTION DECLARATIONS **********************/
-///////////////////
-// AES
-///////////////////
-// Key setup must be done before any AES en/de-cryption functions can be used.
-void _olm_aes_key_setup(const BYTE key[],          // The key, must be 128, 192, or 256 bits
-                   WORD w[],                  // Output key schedule to be used later
-                   int keysize);              // Bit length of the key, 128, 192, or 256
-
-void _olm_aes_encrypt(const BYTE in[],             // 16 bytes of plaintext
-                 BYTE out[],                  // 16 bytes of ciphertext
-                 const WORD key[],            // From the key setup
-                 int keysize);                // Bit length of the key, 128, 192, or 256
-
-void _olm_aes_decrypt(const BYTE in[],             // 16 bytes of ciphertext
-                 BYTE out[],                  // 16 bytes of plaintext
-                 const WORD key[],            // From the key setup
-                 int keysize);                // Bit length of the key, 128, 192, or 256
-
-///////////////////
-// AES - CBC
-///////////////////
-int _olm_aes_encrypt_cbc(const BYTE in[],          // Plaintext
-                    size_t in_len,            // Must be a multiple of AES_BLOCK_SIZE
-                    BYTE out[],               // Ciphertext, same length as plaintext
-                    const WORD key[],         // From the key setup
-                    int keysize,              // Bit length of the key, 128, 192, or 256
-                    const BYTE iv[]);         // IV, must be AES_BLOCK_SIZE bytes long
-
-// Only output the CBC-MAC of the input.
-int _olm_aes_encrypt_cbc_mac(const BYTE in[],      // plaintext
-                        size_t in_len,        // Must be a multiple of AES_BLOCK_SIZE
-                        BYTE out[],           // Output MAC
-                        const WORD key[],     // From the key setup
-                        int keysize,          // Bit length of the key, 128, 192, or 256
-                        const BYTE iv[]);     // IV, must be AES_BLOCK_SIZE bytes long
-
-///////////////////
-// AES - CTR
-///////////////////
-void increment_iv(BYTE iv[],                  // Must be a multiple of AES_BLOCK_SIZE
-                  int counter_size);          // Bytes of the IV used for counting (low end)
-
-void _olm_aes_encrypt_ctr(const BYTE in[],         // Plaintext
-                     size_t in_len,           // Any byte length
-                     BYTE out[],              // Ciphertext, same length as plaintext
-                     const WORD key[],        // From the key setup
-                     int keysize,             // Bit length of the key, 128, 192, or 256
-                     const BYTE iv[]);        // IV, must be AES_BLOCK_SIZE bytes long
-
-void _olm_aes_decrypt_ctr(const BYTE in[],         // Ciphertext
-                     size_t in_len,           // Any byte length
-                     BYTE out[],              // Plaintext, same length as ciphertext
-                     const WORD key[],        // From the key setup
-                     int keysize,             // Bit length of the key, 128, 192, or 256
-                     const BYTE iv[]);        // IV, must be AES_BLOCK_SIZE bytes long
-
-///////////////////
-// AES - CCM
-///////////////////
-// Returns True if the input parameters do not violate any constraint.
-int _olm_aes_encrypt_ccm(const BYTE plaintext[],              // IN  - Plaintext.
-                    WORD plaintext_len,                  // IN  - Plaintext length.
-                    const BYTE associated_data[],        // IN  - Associated Data included in authentication, but not encryption.
-                    unsigned short associated_data_len,  // IN  - Associated Data length in bytes.
-                    const BYTE nonce[],                  // IN  - The Nonce to be used for encryption.
-                    unsigned short nonce_len,            // IN  - Nonce length in bytes.
-                    BYTE ciphertext[],                   // OUT - Ciphertext, a concatination of the plaintext and the MAC.
-                    WORD *ciphertext_len,                // OUT - The length of the ciphertext, always plaintext_len + mac_len.
-                    WORD mac_len,                        // IN  - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16.
-                    const BYTE key[],                    // IN  - The AES key for encryption.
-                    int keysize);                        // IN  - The length of the key in bits. Valid values are 128, 192, 256.
-
-// Returns True if the input parameters do not violate any constraint.
-// Use mac_auth to ensure decryption/validation was preformed correctly.
-// If authentication does not succeed, the plaintext is zeroed out. To overwride
-// this, call with mac_auth = NULL. The proper proceedure is to decrypt with
-// authentication enabled (mac_auth != NULL) and make a second call to that
-// ignores authentication explicitly if the first call failes.
-int _olm_aes_decrypt_ccm(const BYTE ciphertext[],             // IN  - Ciphertext, the concatination of encrypted plaintext and MAC.
-                    WORD ciphertext_len,                 // IN  - Ciphertext length in bytes.
-                    const BYTE assoc[],                  // IN  - The Associated Data, required for authentication.
-                    unsigned short assoc_len,            // IN  - Associated Data length in bytes.
-                    const BYTE nonce[],                  // IN  - The Nonce to use for decryption, same one as for encryption.
-                    unsigned short nonce_len,            // IN  - Nonce length in bytes.
-                    BYTE plaintext[],                    // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - mac_len.
-                    WORD *plaintext_len,                 // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len .
-                    WORD mac_len,                        // IN  - The length of the MAC that was calculated.
-                    int *mac_auth,                       // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the authentication.
-                    const BYTE key[],                    // IN  - The AES key for decryption.
-                    int keysize);                        // IN  - The length of the key in BITS. Valid values are 128, 192, 256.
-
-///////////////////
-// Test functions
-///////////////////
-int aes_test();
-int aes_ecb_test();
-int aes_cbc_test();
-int aes_ctr_test();
-int aes_ccm_test();
-
-#endif   // AES_H
+/*********************************************************************\r
+* Filename:   aes.h\r
+* Author:     Brad Conte (brad AT bradconte.com)\r
+* Copyright:\r
+* Disclaimer: This code is presented "as is" without any guarantees.\r
+* Details:    Defines the API for the corresponding AES implementation.\r
+*********************************************************************/\r
+\r
+#ifndef AES_H\r
+#define AES_H\r
+\r
+/*************************** HEADER FILES ***************************/\r
+#include <stddef.h>\r
+\r
+/****************************** MACROS ******************************/\r
+#define AES_BLOCK_SIZE 16               // AES operates on 16 bytes at a time\r
+\r
+/**************************** DATA TYPES ****************************/\r
+typedef unsigned char BYTE;            // 8-bit byte\r
+typedef unsigned int WORD;             // 32-bit word, change to "long" for 16-bit machines\r
+\r
+/*********************** FUNCTION DECLARATIONS **********************/\r
+///////////////////\r
+// AES\r
+///////////////////\r
+// Key setup must be done before any AES en/de-cryption functions can be used.\r
+void _olm_aes_key_setup(const BYTE key[],          // The key, must be 128, 192, or 256 bits\r
+                   WORD w[],                  // Output key schedule to be used later\r
+                   int keysize);              // Bit length of the key, 128, 192, or 256\r
+\r
+void _olm_aes_encrypt(const BYTE in[],             // 16 bytes of plaintext\r
+                 BYTE out[],                  // 16 bytes of ciphertext\r
+                 const WORD key[],            // From the key setup\r
+                 int keysize);                // Bit length of the key, 128, 192, or 256\r
+\r
+void _olm_aes_decrypt(const BYTE in[],             // 16 bytes of ciphertext\r
+                 BYTE out[],                  // 16 bytes of plaintext\r
+                 const WORD key[],            // From the key setup\r
+                 int keysize);                // Bit length of the key, 128, 192, or 256\r
+\r
+///////////////////\r
+// AES - CBC\r
+///////////////////\r
+int _olm_aes_encrypt_cbc(const BYTE in[],          // Plaintext\r
+                    size_t in_len,            // Must be a multiple of AES_BLOCK_SIZE\r
+                    BYTE out[],               // Ciphertext, same length as plaintext\r
+                    const WORD key[],         // From the key setup\r
+                    int keysize,              // Bit length of the key, 128, 192, or 256\r
+                    const BYTE iv[]);         // IV, must be AES_BLOCK_SIZE bytes long\r
+\r
+// Only output the CBC-MAC of the input.\r
+int _olm_aes_encrypt_cbc_mac(const BYTE in[],      // plaintext\r
+                        size_t in_len,        // Must be a multiple of AES_BLOCK_SIZE\r
+                        BYTE out[],           // Output MAC\r
+                        const WORD key[],     // From the key setup\r
+                        int keysize,          // Bit length of the key, 128, 192, or 256\r
+                        const BYTE iv[]);     // IV, must be AES_BLOCK_SIZE bytes long\r
+\r
+///////////////////\r
+// AES - CTR\r
+///////////////////\r
+void increment_iv(BYTE iv[],                  // Must be a multiple of AES_BLOCK_SIZE\r
+                  int counter_size);          // Bytes of the IV used for counting (low end)\r
+\r
+void _olm_aes_encrypt_ctr(const BYTE in[],         // Plaintext\r
+                     size_t in_len,           // Any byte length\r
+                     BYTE out[],              // Ciphertext, same length as plaintext\r
+                     const WORD key[],        // From the key setup\r
+                     int keysize,             // Bit length of the key, 128, 192, or 256\r
+                     const BYTE iv[]);        // IV, must be AES_BLOCK_SIZE bytes long\r
+\r
+void _olm_aes_decrypt_ctr(const BYTE in[],         // Ciphertext\r
+                     size_t in_len,           // Any byte length\r
+                     BYTE out[],              // Plaintext, same length as ciphertext\r
+                     const WORD key[],        // From the key setup\r
+                     int keysize,             // Bit length of the key, 128, 192, or 256\r
+                     const BYTE iv[]);        // IV, must be AES_BLOCK_SIZE bytes long\r
+\r
+///////////////////\r
+// AES - CCM\r
+///////////////////\r
+// Returns True if the input parameters do not violate any constraint.\r
+int _olm_aes_encrypt_ccm(const BYTE plaintext[],              // IN  - Plaintext.\r
+                    WORD plaintext_len,                  // IN  - Plaintext length.\r
+                    const BYTE associated_data[],        // IN  - Associated Data included in authentication, but not encryption.\r
+                    unsigned short associated_data_len,  // IN  - Associated Data length in bytes.\r
+                    const BYTE nonce[],                  // IN  - The Nonce to be used for encryption.\r
+                    unsigned short nonce_len,            // IN  - Nonce length in bytes.\r
+                    BYTE ciphertext[],                   // OUT - Ciphertext, a concatination of the plaintext and the MAC.\r
+                    WORD *ciphertext_len,                // OUT - The length of the ciphertext, always plaintext_len + mac_len.\r
+                    WORD mac_len,                        // IN  - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16.\r
+                    const BYTE key[],                    // IN  - The AES key for encryption.\r
+                    int keysize);                        // IN  - The length of the key in bits. Valid values are 128, 192, 256.\r
+\r
+// Returns True if the input parameters do not violate any constraint.\r
+// Use mac_auth to ensure decryption/validation was preformed correctly.\r
+// If authentication does not succeed, the plaintext is zeroed out. To overwride\r
+// this, call with mac_auth = NULL. The proper proceedure is to decrypt with\r
+// authentication enabled (mac_auth != NULL) and make a second call to that\r
+// ignores authentication explicitly if the first call failes.\r
+int _olm_aes_decrypt_ccm(const BYTE ciphertext[],             // IN  - Ciphertext, the concatination of encrypted plaintext and MAC.\r
+                    WORD ciphertext_len,                 // IN  - Ciphertext length in bytes.\r
+                    const BYTE assoc[],                  // IN  - The Associated Data, required for authentication.\r
+                    unsigned short assoc_len,            // IN  - Associated Data length in bytes.\r
+                    const BYTE nonce[],                  // IN  - The Nonce to use for decryption, same one as for encryption.\r
+                    unsigned short nonce_len,            // IN  - Nonce length in bytes.\r
+                    BYTE plaintext[],                    // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - mac_len.\r
+                    WORD *plaintext_len,                 // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len .\r
+                    WORD mac_len,                        // IN  - The length of the MAC that was calculated.\r
+                    int *mac_auth,                       // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the authentication.\r
+                    const BYTE key[],                    // IN  - The AES key for decryption.\r
+                    int keysize);                        // IN  - The length of the key in BITS. Valid values are 128, 192, 256.\r
+\r
+///////////////////\r
+// Test functions\r
+///////////////////\r
+int aes_test();\r
+int aes_ecb_test();\r
+int aes_cbc_test();\r
+int aes_ctr_test();\r
+int aes_ccm_test();\r
+\r
+#endif   // AES_H\r
index b679477e18d474a63431f540c9dac302c89ee95b..d49726d0abe779f61ac942211ad003bac4725e83 100644 (file)
-/*********************************************************************
-* Filename:   aes_test.c
-* Author:     Brad Conte (brad AT bradconte.com)
-* Copyright:
-* Disclaimer: This code is presented "as is" without any guarantees.
-* Details:    Performs known-answer tests on the corresponding AES
-              implementation. These tests do not encompass the full
-              range of available test vectors and are not sufficient
-              for FIPS-140 certification. However, if the tests pass
-              it is very, very likely that the code is correct and was
-              compiled properly. This code also serves as
-                 example usage of the functions.
-*********************************************************************/
-
-/*************************** HEADER FILES ***************************/
-#include <stdio.h>
-#include <memory.h>
-#include "aes.h"
-
-/*********************** FUNCTION DEFINITIONS ***********************/
-void print_hex(BYTE str[], int len)
-{
-       int idx;
-
-       for(idx = 0; idx < len; idx++)
-               printf("%02x", str[idx]);
-}
-
-int aes_ecb_test()
-{
-       WORD key_schedule[60], idx;
-       BYTE enc_buf[128];
-       BYTE plaintext[2][16] = {
-               {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a},
-               {0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}
-       };
-       BYTE ciphertext[2][16] = {
-               {0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c,0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8},
-               {0x59,0x1c,0xcb,0x10,0xd4,0x10,0xed,0x26,0xdc,0x5b,0xa7,0x4a,0x31,0x36,0x28,0x70}
-       };
-       BYTE key[1][32] = {
-               {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}
-       };
-       int pass = 1;
-
-       // Raw ECB mode.
-       //printf("* ECB mode:\n");
-       aes_key_setup(key[0], key_schedule, 256);
-       //printf(  "Key          : ");
-       //print_hex(key[0], 32);
-
-       for(idx = 0; idx < 2; idx++) {
-               aes_encrypt(plaintext[idx], enc_buf, key_schedule, 256);
-               //printf("\nPlaintext    : ");
-               //print_hex(plaintext[idx], 16);
-               //printf("\n-encrypted to: ");
-               //print_hex(enc_buf, 16);
-               pass = pass && !memcmp(enc_buf, ciphertext[idx], 16);
-
-               aes_decrypt(ciphertext[idx], enc_buf, key_schedule, 256);
-               //printf("\nCiphertext   : ");
-               //print_hex(ciphertext[idx], 16);
-               //printf("\n-decrypted to: ");
-               //print_hex(enc_buf, 16);
-               pass = pass && !memcmp(enc_buf, plaintext[idx], 16);
-
-               //printf("\n\n");
-       }
-
-       return(pass);
-}
-
-int aes_cbc_test()
-{
-       WORD key_schedule[60];
-       BYTE enc_buf[128];
-       BYTE plaintext[1][32] = {
-               {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}
-       };
-       BYTE ciphertext[2][32] = {
-               {0xf5,0x8c,0x4c,0x04,0xd6,0xe5,0xf1,0xba,0x77,0x9e,0xab,0xfb,0x5f,0x7b,0xfb,0xd6,0x9c,0xfc,0x4e,0x96,0x7e,0xdb,0x80,0x8d,0x67,0x9f,0x77,0x7b,0xc6,0x70,0x2c,0x7d}
-       };
-       BYTE iv[1][16] = {
-               {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}
-       };
-       BYTE key[1][32] = {
-               {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}
-       };
-       int pass = 1;
-
-       //printf("* CBC mode:\n");
-       aes_key_setup(key[0], key_schedule, 256);
-
-       //printf(  "Key          : ");
-       //print_hex(key[0], 32);
-       //printf("\nIV           : ");
-       //print_hex(iv[0], 16);
-
-       aes_encrypt_cbc(plaintext[0], 32, enc_buf, key_schedule, 256, iv[0]);
-       //printf("\nPlaintext    : ");
-       //print_hex(plaintext[0], 32);
-       //printf("\n-encrypted to: ");
-       //print_hex(enc_buf, 32);
-       //printf("\nCiphertext   : ");
-       //print_hex(ciphertext[0], 32);
-       pass = pass && !memcmp(enc_buf, ciphertext[0], 32);
-
-       //printf("\n\n");
-       return(pass);
-}
-
-int aes_ctr_test()
-{
-       WORD key_schedule[60];
-       BYTE enc_buf[128];
-       BYTE plaintext[1][32] = {
-               {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}
-       };
-       BYTE ciphertext[1][32] = {
-               {0x60,0x1e,0xc3,0x13,0x77,0x57,0x89,0xa5,0xb7,0xa7,0xf5,0x04,0xbb,0xf3,0xd2,0x28,0xf4,0x43,0xe3,0xca,0x4d,0x62,0xb5,0x9a,0xca,0x84,0xe9,0x90,0xca,0xca,0xf5,0xc5}
-       };
-       BYTE iv[1][16] = {
-               {0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff},
-       };
-       BYTE key[1][32] = {
-               {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}
-       };
-       int pass = 1;
-
-       //printf("* CTR mode:\n");
-       aes_key_setup(key[0], key_schedule, 256);
-
-       //printf(  "Key          : ");
-       //print_hex(key[0], 32);
-       //printf("\nIV           : ");
-       //print_hex(iv[0], 16);
-
-       aes_encrypt_ctr(plaintext[0], 32, enc_buf, key_schedule, 256, iv[0]);
-       //printf("\nPlaintext    : ");
-       //print_hex(plaintext[0], 32);
-       //printf("\n-encrypted to: ");
-       //print_hex(enc_buf, 32);
-       pass = pass && !memcmp(enc_buf, ciphertext[0], 32);
-
-       aes_decrypt_ctr(ciphertext[0], 32, enc_buf, key_schedule, 256, iv[0]);
-       //printf("\nCiphertext   : ");
-       //print_hex(ciphertext[0], 32);
-       //printf("\n-decrypted to: ");
-       //print_hex(enc_buf, 32);
-       pass = pass && !memcmp(enc_buf, plaintext[0], 32);
-
-       //printf("\n\n");
-       return(pass);
-}
-
-int aes_ccm_test()
-{
-       int mac_auth;
-       WORD enc_buf_len;
-       BYTE enc_buf[128];
-       BYTE plaintext[3][32] = {
-               {0x20,0x21,0x22,0x23},
-               {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f},
-               {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}
-       };
-       BYTE assoc[3][32] = {
-               {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07},
-               {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f},
-               {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13}
-       };
-       BYTE ciphertext[3][32 + 16] = {
-               {0x71,0x62,0x01,0x5b,0x4d,0xac,0x25,0x5d},
-               {0xd2,0xa1,0xf0,0xe0,0x51,0xea,0x5f,0x62,0x08,0x1a,0x77,0x92,0x07,0x3d,0x59,0x3d,0x1f,0xc6,0x4f,0xbf,0xac,0xcd},
-               {0xe3,0xb2,0x01,0xa9,0xf5,0xb7,0x1a,0x7a,0x9b,0x1c,0xea,0xec,0xcd,0x97,0xe7,0x0b,0x61,0x76,0xaa,0xd9,0xa4,0x42,0x8a,0xa5,0x48,0x43,0x92,0xfb,0xc1,0xb0,0x99,0x51}
-       };
-       BYTE iv[3][16] = {
-               {0x10,0x11,0x12,0x13,0x14,0x15,0x16},
-               {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17},
-               {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b}
-       };
-       BYTE key[1][32] = {
-               {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}
-       };
-       int pass = 1;
-
-       //printf("* CCM mode:\n");
-       //printf("Key           : ");
-       //print_hex(key[0], 16);
-
-       //print_hex(plaintext[0], 4);
-       //print_hex(assoc[0], 8);
-       //print_hex(ciphertext[0], 8);
-       //print_hex(iv[0], 7);
-       //print_hex(key[0], 16);
-
-       aes_encrypt_ccm(plaintext[0], 4, assoc[0], 8, iv[0], 7, enc_buf, &enc_buf_len, 4, key[0], 128);
-       //printf("\nNONCE        : ");
-       //print_hex(iv[0], 7);
-       //printf("\nAssoc. Data  : ");
-       //print_hex(assoc[0], 8);
-       //printf("\nPayload       : ");
-       //print_hex(plaintext[0], 4);
-       //printf("\n-encrypted to: ");
-       //print_hex(enc_buf, enc_buf_len);
-       pass = pass && !memcmp(enc_buf, ciphertext[0], enc_buf_len);
-
-       aes_decrypt_ccm(ciphertext[0], 8, assoc[0], 8, iv[0], 7, enc_buf, &enc_buf_len, 4, &mac_auth, key[0], 128);
-       //printf("\n-Ciphertext  : ");
-       //print_hex(ciphertext[0], 8);
-       //printf("\n-decrypted to: ");
-       //print_hex(enc_buf, enc_buf_len);
-       //printf("\nAuthenticated: %d ", mac_auth);
-       pass = pass && !memcmp(enc_buf, plaintext[0], enc_buf_len) && mac_auth;
-
-
-       aes_encrypt_ccm(plaintext[1], 16, assoc[1], 16, iv[1], 8, enc_buf, &enc_buf_len, 6, key[0], 128);
-       //printf("\n\nNONCE        : ");
-       //print_hex(iv[1], 8);
-       //printf("\nAssoc. Data  : ");
-       //print_hex(assoc[1], 16);
-       //printf("\nPayload      : ");
-       //print_hex(plaintext[1], 16);
-       //printf("\n-encrypted to: ");
-       //print_hex(enc_buf, enc_buf_len);
-       pass = pass && !memcmp(enc_buf, ciphertext[1], enc_buf_len);
-
-       aes_decrypt_ccm(ciphertext[1], 22, assoc[1], 16, iv[1], 8, enc_buf, &enc_buf_len, 6, &mac_auth, key[0], 128);
-       //printf("\n-Ciphertext  : ");
-       //print_hex(ciphertext[1], 22);
-       //printf("\n-decrypted to: ");
-       //print_hex(enc_buf, enc_buf_len);
-       //printf("\nAuthenticated: %d ", mac_auth);
-       pass = pass && !memcmp(enc_buf, plaintext[1], enc_buf_len) && mac_auth;
-
-
-       aes_encrypt_ccm(plaintext[2], 24, assoc[2], 20, iv[2], 12, enc_buf, &enc_buf_len, 8, key[0], 128);
-       //printf("\n\nNONCE        : ");
-       //print_hex(iv[2], 12);
-       //printf("\nAssoc. Data  : ");
-       //print_hex(assoc[2], 20);
-       //printf("\nPayload      : ");
-       //print_hex(plaintext[2], 24);
-       //printf("\n-encrypted to: ");
-       //print_hex(enc_buf, enc_buf_len);
-       pass = pass && !memcmp(enc_buf, ciphertext[2], enc_buf_len);
-
-       aes_decrypt_ccm(ciphertext[2], 32, assoc[2], 20, iv[2], 12, enc_buf, &enc_buf_len, 8, &mac_auth, key[0], 128);
-       //printf("\n-Ciphertext  : ");
-       //print_hex(ciphertext[2], 32);
-       //printf("\n-decrypted to: ");
-       //print_hex(enc_buf, enc_buf_len);
-       //printf("\nAuthenticated: %d ", mac_auth);
-       pass = pass && !memcmp(enc_buf, plaintext[2], enc_buf_len) && mac_auth;
-
-       //printf("\n\n");
-       return(pass);
-}
-
-int aes_test()
-{
-       int pass = 1;
-
-       pass = pass && aes_ecb_test();
-       pass = pass && aes_cbc_test();
-       pass = pass && aes_ctr_test();
-       pass = pass && aes_ccm_test();
-
-       return(pass);
-}
-
-int main(int argc, char *argv[])
-{
-       printf("AES Tests: %s\n", aes_test() ? "SUCCEEDED" : "FAILED");
-
-       return(0);
-}
+/*********************************************************************\r
+* Filename:   aes_test.c\r
+* Author:     Brad Conte (brad AT bradconte.com)\r
+* Copyright:\r
+* Disclaimer: This code is presented "as is" without any guarantees.\r
+* Details:    Performs known-answer tests on the corresponding AES\r
+              implementation. These tests do not encompass the full\r
+              range of available test vectors and are not sufficient\r
+              for FIPS-140 certification. However, if the tests pass\r
+              it is very, very likely that the code is correct and was\r
+              compiled properly. This code also serves as\r
+                 example usage of the functions.\r
+*********************************************************************/\r
+\r
+/*************************** HEADER FILES ***************************/\r
+#include <stdio.h>\r
+#include <memory.h>\r
+#include "aes.h"\r
+\r
+/*********************** FUNCTION DEFINITIONS ***********************/\r
+void print_hex(BYTE str[], int len)\r
+{\r
+       int idx;\r
+\r
+       for(idx = 0; idx < len; idx++)\r
+               printf("%02x", str[idx]);\r
+}\r
+\r
+int aes_ecb_test()\r
+{\r
+       WORD key_schedule[60], idx;\r
+       BYTE enc_buf[128];\r
+       BYTE plaintext[2][16] = {\r
+               {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a},\r
+               {0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}\r
+       };\r
+       BYTE ciphertext[2][16] = {\r
+               {0xf3,0xee,0xd1,0xbd,0xb5,0xd2,0xa0,0x3c,0x06,0x4b,0x5a,0x7e,0x3d,0xb1,0x81,0xf8},\r
+               {0x59,0x1c,0xcb,0x10,0xd4,0x10,0xed,0x26,0xdc,0x5b,0xa7,0x4a,0x31,0x36,0x28,0x70}\r
+       };\r
+       BYTE key[1][32] = {\r
+               {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}\r
+       };\r
+       int pass = 1;\r
+\r
+       // Raw ECB mode.\r
+       //printf("* ECB mode:\n");\r
+       aes_key_setup(key[0], key_schedule, 256);\r
+       //printf(  "Key          : ");\r
+       //print_hex(key[0], 32);\r
+\r
+       for(idx = 0; idx < 2; idx++) {\r
+               aes_encrypt(plaintext[idx], enc_buf, key_schedule, 256);\r
+               //printf("\nPlaintext    : ");\r
+               //print_hex(plaintext[idx], 16);\r
+               //printf("\n-encrypted to: ");\r
+               //print_hex(enc_buf, 16);\r
+               pass = pass && !memcmp(enc_buf, ciphertext[idx], 16);\r
+\r
+               aes_decrypt(ciphertext[idx], enc_buf, key_schedule, 256);\r
+               //printf("\nCiphertext   : ");\r
+               //print_hex(ciphertext[idx], 16);\r
+               //printf("\n-decrypted to: ");\r
+               //print_hex(enc_buf, 16);\r
+               pass = pass && !memcmp(enc_buf, plaintext[idx], 16);\r
+\r
+               //printf("\n\n");\r
+       }\r
+\r
+       return(pass);\r
+}\r
+\r
+int aes_cbc_test()\r
+{\r
+       WORD key_schedule[60];\r
+       BYTE enc_buf[128];\r
+       BYTE plaintext[1][32] = {\r
+               {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}\r
+       };\r
+       BYTE ciphertext[2][32] = {\r
+               {0xf5,0x8c,0x4c,0x04,0xd6,0xe5,0xf1,0xba,0x77,0x9e,0xab,0xfb,0x5f,0x7b,0xfb,0xd6,0x9c,0xfc,0x4e,0x96,0x7e,0xdb,0x80,0x8d,0x67,0x9f,0x77,0x7b,0xc6,0x70,0x2c,0x7d}\r
+       };\r
+       BYTE iv[1][16] = {\r
+               {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}\r
+       };\r
+       BYTE key[1][32] = {\r
+               {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}\r
+       };\r
+       int pass = 1;\r
+\r
+       //printf("* CBC mode:\n");\r
+       aes_key_setup(key[0], key_schedule, 256);\r
+\r
+       //printf(  "Key          : ");\r
+       //print_hex(key[0], 32);\r
+       //printf("\nIV           : ");\r
+       //print_hex(iv[0], 16);\r
+\r
+       aes_encrypt_cbc(plaintext[0], 32, enc_buf, key_schedule, 256, iv[0]);\r
+       //printf("\nPlaintext    : ");\r
+       //print_hex(plaintext[0], 32);\r
+       //printf("\n-encrypted to: ");\r
+       //print_hex(enc_buf, 32);\r
+       //printf("\nCiphertext   : ");\r
+       //print_hex(ciphertext[0], 32);\r
+       pass = pass && !memcmp(enc_buf, ciphertext[0], 32);\r
+\r
+       //printf("\n\n");\r
+       return(pass);\r
+}\r
+\r
+int aes_ctr_test()\r
+{\r
+       WORD key_schedule[60];\r
+       BYTE enc_buf[128];\r
+       BYTE plaintext[1][32] = {\r
+               {0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51}\r
+       };\r
+       BYTE ciphertext[1][32] = {\r
+               {0x60,0x1e,0xc3,0x13,0x77,0x57,0x89,0xa5,0xb7,0xa7,0xf5,0x04,0xbb,0xf3,0xd2,0x28,0xf4,0x43,0xe3,0xca,0x4d,0x62,0xb5,0x9a,0xca,0x84,0xe9,0x90,0xca,0xca,0xf5,0xc5}\r
+       };\r
+       BYTE iv[1][16] = {\r
+               {0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff},\r
+       };\r
+       BYTE key[1][32] = {\r
+               {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}\r
+       };\r
+       int pass = 1;\r
+\r
+       //printf("* CTR mode:\n");\r
+       aes_key_setup(key[0], key_schedule, 256);\r
+\r
+       //printf(  "Key          : ");\r
+       //print_hex(key[0], 32);\r
+       //printf("\nIV           : ");\r
+       //print_hex(iv[0], 16);\r
+\r
+       aes_encrypt_ctr(plaintext[0], 32, enc_buf, key_schedule, 256, iv[0]);\r
+       //printf("\nPlaintext    : ");\r
+       //print_hex(plaintext[0], 32);\r
+       //printf("\n-encrypted to: ");\r
+       //print_hex(enc_buf, 32);\r
+       pass = pass && !memcmp(enc_buf, ciphertext[0], 32);\r
+\r
+       aes_decrypt_ctr(ciphertext[0], 32, enc_buf, key_schedule, 256, iv[0]);\r
+       //printf("\nCiphertext   : ");\r
+       //print_hex(ciphertext[0], 32);\r
+       //printf("\n-decrypted to: ");\r
+       //print_hex(enc_buf, 32);\r
+       pass = pass && !memcmp(enc_buf, plaintext[0], 32);\r
+\r
+       //printf("\n\n");\r
+       return(pass);\r
+}\r
+\r
+int aes_ccm_test()\r
+{\r
+       int mac_auth;\r
+       WORD enc_buf_len;\r
+       BYTE enc_buf[128];\r
+       BYTE plaintext[3][32] = {\r
+               {0x20,0x21,0x22,0x23},\r
+               {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f},\r
+               {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}\r
+       };\r
+       BYTE assoc[3][32] = {\r
+               {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07},\r
+               {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f},\r
+               {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13}\r
+       };\r
+       BYTE ciphertext[3][32 + 16] = {\r
+               {0x71,0x62,0x01,0x5b,0x4d,0xac,0x25,0x5d},\r
+               {0xd2,0xa1,0xf0,0xe0,0x51,0xea,0x5f,0x62,0x08,0x1a,0x77,0x92,0x07,0x3d,0x59,0x3d,0x1f,0xc6,0x4f,0xbf,0xac,0xcd},\r
+               {0xe3,0xb2,0x01,0xa9,0xf5,0xb7,0x1a,0x7a,0x9b,0x1c,0xea,0xec,0xcd,0x97,0xe7,0x0b,0x61,0x76,0xaa,0xd9,0xa4,0x42,0x8a,0xa5,0x48,0x43,0x92,0xfb,0xc1,0xb0,0x99,0x51}\r
+       };\r
+       BYTE iv[3][16] = {\r
+               {0x10,0x11,0x12,0x13,0x14,0x15,0x16},\r
+               {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17},\r
+               {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b}\r
+       };\r
+       BYTE key[1][32] = {\r
+               {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f}\r
+       };\r
+       int pass = 1;\r
+\r
+       //printf("* CCM mode:\n");\r
+       //printf("Key           : ");\r
+       //print_hex(key[0], 16);\r
+\r
+       //print_hex(plaintext[0], 4);\r
+       //print_hex(assoc[0], 8);\r
+       //print_hex(ciphertext[0], 8);\r
+       //print_hex(iv[0], 7);\r
+       //print_hex(key[0], 16);\r
+\r
+       aes_encrypt_ccm(plaintext[0], 4, assoc[0], 8, iv[0], 7, enc_buf, &enc_buf_len, 4, key[0], 128);\r
+       //printf("\nNONCE        : ");\r
+       //print_hex(iv[0], 7);\r
+       //printf("\nAssoc. Data  : ");\r
+       //print_hex(assoc[0], 8);\r
+       //printf("\nPayload       : ");\r
+       //print_hex(plaintext[0], 4);\r
+       //printf("\n-encrypted to: ");\r
+       //print_hex(enc_buf, enc_buf_len);\r
+       pass = pass && !memcmp(enc_buf, ciphertext[0], enc_buf_len);\r
+\r
+       aes_decrypt_ccm(ciphertext[0], 8, assoc[0], 8, iv[0], 7, enc_buf, &enc_buf_len, 4, &mac_auth, key[0], 128);\r
+       //printf("\n-Ciphertext  : ");\r
+       //print_hex(ciphertext[0], 8);\r
+       //printf("\n-decrypted to: ");\r
+       //print_hex(enc_buf, enc_buf_len);\r
+       //printf("\nAuthenticated: %d ", mac_auth);\r
+       pass = pass && !memcmp(enc_buf, plaintext[0], enc_buf_len) && mac_auth;\r
+\r
+\r
+       aes_encrypt_ccm(plaintext[1], 16, assoc[1], 16, iv[1], 8, enc_buf, &enc_buf_len, 6, key[0], 128);\r
+       //printf("\n\nNONCE        : ");\r
+       //print_hex(iv[1], 8);\r
+       //printf("\nAssoc. Data  : ");\r
+       //print_hex(assoc[1], 16);\r
+       //printf("\nPayload      : ");\r
+       //print_hex(plaintext[1], 16);\r
+       //printf("\n-encrypted to: ");\r
+       //print_hex(enc_buf, enc_buf_len);\r
+       pass = pass && !memcmp(enc_buf, ciphertext[1], enc_buf_len);\r
+\r
+       aes_decrypt_ccm(ciphertext[1], 22, assoc[1], 16, iv[1], 8, enc_buf, &enc_buf_len, 6, &mac_auth, key[0], 128);\r
+       //printf("\n-Ciphertext  : ");\r
+       //print_hex(ciphertext[1], 22);\r
+       //printf("\n-decrypted to: ");\r
+       //print_hex(enc_buf, enc_buf_len);\r
+       //printf("\nAuthenticated: %d ", mac_auth);\r
+       pass = pass && !memcmp(enc_buf, plaintext[1], enc_buf_len) && mac_auth;\r
+\r
+\r
+       aes_encrypt_ccm(plaintext[2], 24, assoc[2], 20, iv[2], 12, enc_buf, &enc_buf_len, 8, key[0], 128);\r
+       //printf("\n\nNONCE        : ");\r
+       //print_hex(iv[2], 12);\r
+       //printf("\nAssoc. Data  : ");\r
+       //print_hex(assoc[2], 20);\r
+       //printf("\nPayload      : ");\r
+       //print_hex(plaintext[2], 24);\r
+       //printf("\n-encrypted to: ");\r
+       //print_hex(enc_buf, enc_buf_len);\r
+       pass = pass && !memcmp(enc_buf, ciphertext[2], enc_buf_len);\r
+\r
+       aes_decrypt_ccm(ciphertext[2], 32, assoc[2], 20, iv[2], 12, enc_buf, &enc_buf_len, 8, &mac_auth, key[0], 128);\r
+       //printf("\n-Ciphertext  : ");\r
+       //print_hex(ciphertext[2], 32);\r
+       //printf("\n-decrypted to: ");\r
+       //print_hex(enc_buf, enc_buf_len);\r
+       //printf("\nAuthenticated: %d ", mac_auth);\r
+       pass = pass && !memcmp(enc_buf, plaintext[2], enc_buf_len) && mac_auth;\r
+\r
+       //printf("\n\n");\r
+       return(pass);\r
+}\r
+\r
+int aes_test()\r
+{\r
+       int pass = 1;\r
+\r
+       pass = pass && aes_ecb_test();\r
+       pass = pass && aes_cbc_test();\r
+       pass = pass && aes_ctr_test();\r
+       pass = pass && aes_ccm_test();\r
+\r
+       return(pass);\r
+}\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+       printf("AES Tests: %s\n", aes_test() ? "SUCCEEDED" : "FAILED");\r
+\r
+       return(0);\r
+}\r
index 2bdfb50466d494f7d2ad437324d500e128d2ebe9..2cc4cfe418dce33d03d3a9471848011e150dd594 100644 (file)
-#include <string.h>
-#include <sys/param.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include "esp_log.h"
-#include "nvs_flash.h"
-#include "esp_event.h"
-#include "esp_netif.h"
-// #include "protocol_examples_common.h"
-// #include "protocol_examples_utils.h"
-#include "esp_tls.h"
-#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
-#include "esp_crt_bundle.h"
-#endif
-
-#if !CONFIG_IDF_TARGET_LINUX
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "esp_system.h"
-#endif
-
-#include "esp_http_client.h"
-
-/* Root cert for howsmyssl.com, taken from howsmyssl_com_root_cert.pem
-
-   The PEM file was extracted from the output of this command:
-   openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null
-
-   The CA root cert is the last cert given in the chain of certs.
-
-   To embed it in the app binary, the PEM file is named
-   in the component.mk COMPONENT_EMBED_TXTFILES variable.
-*/
-// extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start");
-// extern const char howsmyssl_com_root_cert_pem_end[]   asm("_binary_howsmyssl_com_root_cert_pem_end");
-
-// extern const char postman_root_cert_pem_start[] asm("_binary_postman_root_cert_pem_start");
-// extern const char postman_root_cert_pem_end[]   asm("_binary_postman_root_cert_pem_end");
-
-#include "matrix.h"
-
-#define HTTP_CONNECTION_DATA_SIZE 1024*64
-#define AUTHORIZATION_HEADER_LEN 64
-
-struct MatrixHttpConnection {
-    esp_http_client_handle_t client;
-
-    const char * host;
-    const char * accessToken;
-
-    // char data[HTTP_CONNECTION_DATA_SIZE];
-    char * data;
-    int dataCap;
-    int dataLen;
-};
-
-
-static const char *TAG = "HTTP_CLIENT";
-
-esp_err_t _http_event_handler(esp_http_client_event_t *evt)
-{
-    vTaskDelay(10/portTICK_PERIOD_MS);
-
-    MatrixHttpConnection * hc = (MatrixHttpConnection *)evt->user_data;
-    switch(evt->event_id) {
-        case HTTP_EVENT_ERROR:
-            ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
-            break;
-        case HTTP_EVENT_ON_CONNECTED:
-            ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
-            break;
-        case HTTP_EVENT_HEADER_SENT:
-            ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
-            break;
-        case HTTP_EVENT_ON_HEADER:
-            ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
-            break;
-        case HTTP_EVENT_ON_DATA:
-            ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
-            /*
-             *  Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.
-             *  However, event handler can also be used in case chunked encoding is used.
-             */
-            if (!esp_http_client_is_chunked_response(evt->client)) {
-                ESP_LOGD(TAG, "Non-Chunked Encoding");
-            }
-            else {
-                ESP_LOGD(TAG, "Chunked Encoding");
-            }
-
-            int copy_len = 0;
-
-            // const int64_t buffer_len = esp_http_client_get_content_length(evt->client);
-            // if (buffer_len < hc->dataCap) {
-            //     ESP_LOGE(TAG, "Output buffer too small: %" PRIu64 ", data_len: %d", buffer_len, evt->data_len);
-            //     return ESP_FAIL;
-            // }
-            copy_len = MIN(evt->data_len, (hc->dataCap - hc->dataLen));
-            if (copy_len) {
-                memcpy(hc->data + hc->dataLen, evt->data, copy_len);
-                hc->data[hc->dataLen + copy_len] = '\0';
-            }
-
-            hc->dataLen += copy_len;
-
-            break;
-        case HTTP_EVENT_ON_FINISH:
-            ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
-            break;
-        case HTTP_EVENT_DISCONNECTED:
-            ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
-            int mbedtls_err = 0;
-            esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);
-            if (err != 0) {
-                ESP_LOGI(TAG, "Last esp error code: 0x%x", err);
-                ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
-            }
-            break;
-        case HTTP_EVENT_REDIRECT:
-            ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");
-            // esp_http_client_set_header(evt->client, "From", "user@example.com");
-            // esp_http_client_set_header(evt->client, "Accept", "text/html");
-            // esp_http_client_set_redirection(evt->client);
-            break;
-    }
-    return ESP_OK;
-}
-
-void
-MatrixHttpConnect(
-    MatrixHttpConnection * hc)
-{
-    esp_http_client_config_t config = {
-        .url = hc->host,
-        // .query = "esp",
-        .event_handler = _http_event_handler,
-        .user_data = hc,
-        .disable_auto_redirect = true,
-        .crt_bundle_attach = esp_crt_bundle_attach,
-    };
-
-    hc->client = esp_http_client_init(&config);
-
-    esp_http_client_set_timeout_ms(hc->client, 20000);
-}
-
-void
-MatrixHttpDisconnect(
-    MatrixHttpConnection * hc)
-{
-    esp_http_client_cleanup(hc->client);
-    hc->client = NULL;
-}
-
-bool
-MatrixHttpInit(
-    MatrixHttpConnection ** hc,
-    const char * host)
-{
-    *hc = (MatrixHttpConnection *)calloc(1, sizeof(MatrixHttpConnection));
-    
-    (*hc)->host = host;
-
-    MatrixHttpConnect(*hc);
-
-    return true;
-}
-
-bool
-MatrixHttpDeinit(
-    MatrixHttpConnection ** hc)
-{
-    MatrixHttpDisconnect(*hc);
-
-    free(*hc);
-    *hc = NULL;
-
-    return true;
-}
-
-bool
-MatrixHttpSetAccessToken(
-    MatrixHttpConnection * hc,
-    const char * accessToken)
-{
-    hc->accessToken = accessToken;
-
-    return true;
-}
-
-bool
-MatrixHttpGet(
-    MatrixHttpConnection * hc,
-    const char * url,
-    char * outResponseBuffer, int outResponseCap,
-    bool authenticated)
-{
-    static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
-    if (authenticated)
-        snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
-            "Bearer %s", hc->accessToken);
-    else
-        authorizationHeader[0] = '\0';
-
-    printf("GET %s%s\n", hc->host, url);
-
-    hc->data = outResponseBuffer;
-    hc->dataCap = outResponseCap;
-    hc->dataLen = 0;
-
-    static char hostAndUrl[MAX_URL_LEN];
-    snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
-    
-    esp_http_client_set_url(hc->client, hostAndUrl);
-    esp_http_client_set_method(hc->client, HTTP_METHOD_GET);
-    if (authenticated)
-        esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
-    esp_err_t err = esp_http_client_perform(hc->client);
-    if (err == ESP_OK) {
-        ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRIu64,
-                esp_http_client_get_status_code(hc->client),
-                esp_http_client_get_content_length(hc->client));
-    } else {
-        ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
-    }
-    // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
-
-    return true;
-}
-
-bool
-MatrixHttpPost(
-    MatrixHttpConnection * hc,
-    const char * url,
-    const char * requestBuffer,
-    char * outResponseBuffer, int outResponseCap,
-    bool authenticated)
-{
-    static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
-    if (authenticated)
-        snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
-            "Bearer %s", hc->accessToken);
-    else
-        authorizationHeader[0] = '\0';
-
-    printf("POST %s%s\n%s\n", hc->host, url, requestBuffer);
-
-    hc->data = outResponseBuffer;
-    hc->dataCap = outResponseCap;
-    hc->dataLen = 0;
-
-    static char hostAndUrl[MAX_URL_LEN];
-    snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
-    
-    esp_http_client_set_url(hc->client, hostAndUrl);
-    esp_http_client_set_method(hc->client, HTTP_METHOD_POST);
-    if (authenticated)
-        esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
-    esp_http_client_set_header(hc->client, "Content-Type", "application/json");
-    esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));
-    esp_err_t err = esp_http_client_perform(hc->client);
-    if (err == ESP_OK) {
-        ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRIu64,
-                esp_http_client_get_status_code(hc->client),
-                esp_http_client_get_content_length(hc->client));
-    } else {
-        ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
-    }
-    // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
-
-    return true;
-}
-
-bool
-MatrixHttpPut(
-    MatrixHttpConnection * hc,
-    const char * url,
-    const char * requestBuffer,
-    char * outResponseBuffer, int outResponseCap,
-    bool authenticated)
-{
-    static char authorizationHeader[AUTHORIZATION_HEADER_LEN];
-    if (authenticated)
-        snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,
-            "Bearer %s", hc->accessToken);
-    else
-        authorizationHeader[0] = '\0';
-
-    printf("PUT %s%s\n%s\n", hc->host, url, requestBuffer);
-
-    hc->data = outResponseBuffer;
-    hc->dataCap = outResponseCap;
-    hc->dataLen = 0;
-
-    static char hostAndUrl[MAX_URL_LEN];
-    snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);
-    
-    esp_http_client_set_url(hc->client, hostAndUrl);
-    esp_http_client_set_method(hc->client, HTTP_METHOD_PUT);
-    if (authenticated)
-        esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);
-    esp_http_client_set_header(hc->client, "Content-Type", "application/json");
-    esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));
-    esp_err_t err = esp_http_client_perform(hc->client);
-    if (err == ESP_OK) {
-        ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %"PRIu64,
-                esp_http_client_get_status_code(hc->client),
-                esp_http_client_get_content_length(hc->client));
-    } else {
-        ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));
-    }
-    // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);
-
-    return true;
-}
+#include <string.h>\r
+#include <sys/param.h>\r
+#include <stdlib.h>\r
+#include <ctype.h>\r
+#include "esp_log.h"\r
+#include "nvs_flash.h"\r
+#include "esp_event.h"\r
+#include "esp_netif.h"\r
+// #include "protocol_examples_common.h"\r
+// #include "protocol_examples_utils.h"\r
+#include "esp_tls.h"\r
+#if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE\r
+#include "esp_crt_bundle.h"\r
+#endif\r
+\r
+#if !CONFIG_IDF_TARGET_LINUX\r
+#include "freertos/FreeRTOS.h"\r
+#include "freertos/task.h"\r
+#include "esp_system.h"\r
+#endif\r
+\r
+#include "esp_http_client.h"\r
+\r
+/* Root cert for howsmyssl.com, taken from howsmyssl_com_root_cert.pem\r
+\r
+   The PEM file was extracted from the output of this command:\r
+   openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null\r
+\r
+   The CA root cert is the last cert given in the chain of certs.\r
+\r
+   To embed it in the app binary, the PEM file is named\r
+   in the component.mk COMPONENT_EMBED_TXTFILES variable.\r
+*/\r
+// extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start");\r
+// extern const char howsmyssl_com_root_cert_pem_end[]   asm("_binary_howsmyssl_com_root_cert_pem_end");\r
+\r
+// extern const char postman_root_cert_pem_start[] asm("_binary_postman_root_cert_pem_start");\r
+// extern const char postman_root_cert_pem_end[]   asm("_binary_postman_root_cert_pem_end");\r
+\r
+#include "matrix.h"\r
+\r
+#define HTTP_CONNECTION_DATA_SIZE 1024*64\r
+#define AUTHORIZATION_HEADER_LEN 64\r
+\r
+struct MatrixHttpConnection {\r
+    esp_http_client_handle_t client;\r
+\r
+    const char * host;\r
+    const char * accessToken;\r
+\r
+    // char data[HTTP_CONNECTION_DATA_SIZE];\r
+    char * data;\r
+    int dataCap;\r
+    int dataLen;\r
+};\r
+\r
+\r
+static const char *TAG = "HTTP_CLIENT";\r
+\r
+esp_err_t _http_event_handler(esp_http_client_event_t *evt)\r
+{\r
+    vTaskDelay(10/portTICK_PERIOD_MS);\r
+\r
+    MatrixHttpConnection * hc = (MatrixHttpConnection *)evt->user_data;\r
+    switch(evt->event_id) {\r
+        case HTTP_EVENT_ERROR:\r
+            ESP_LOGD(TAG, "HTTP_EVENT_ERROR");\r
+            break;\r
+        case HTTP_EVENT_ON_CONNECTED:\r
+            ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");\r
+            break;\r
+        case HTTP_EVENT_HEADER_SENT:\r
+            ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");\r
+            break;\r
+        case HTTP_EVENT_ON_HEADER:\r
+            ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);\r
+            break;\r
+        case HTTP_EVENT_ON_DATA:\r
+            ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);\r
+            /*\r
+             *  Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.\r
+             *  However, event handler can also be used in case chunked encoding is used.\r
+             */\r
+            if (!esp_http_client_is_chunked_response(evt->client)) {\r
+                ESP_LOGD(TAG, "Non-Chunked Encoding");\r
+            }\r
+            else {\r
+                ESP_LOGD(TAG, "Chunked Encoding");\r
+            }\r
+\r
+            int copy_len = 0;\r
+\r
+            // const int64_t buffer_len = esp_http_client_get_content_length(evt->client);\r
+            // if (buffer_len < hc->dataCap) {\r
+            //     ESP_LOGE(TAG, "Output buffer too small: %" PRIu64 ", data_len: %d", buffer_len, evt->data_len);\r
+            //     return ESP_FAIL;\r
+            // }\r
+            copy_len = MIN(evt->data_len, (hc->dataCap - hc->dataLen));\r
+            if (copy_len) {\r
+                memcpy(hc->data + hc->dataLen, evt->data, copy_len);\r
+                hc->data[hc->dataLen + copy_len] = '\0';\r
+            }\r
+\r
+            hc->dataLen += copy_len;\r
+\r
+            break;\r
+        case HTTP_EVENT_ON_FINISH:\r
+            ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");\r
+            break;\r
+        case HTTP_EVENT_DISCONNECTED:\r
+            ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");\r
+            int mbedtls_err = 0;\r
+            esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);\r
+            if (err != 0) {\r
+                ESP_LOGI(TAG, "Last esp error code: 0x%x", err);\r
+                ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);\r
+            }\r
+            break;\r
+        case HTTP_EVENT_REDIRECT:\r
+            ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");\r
+            // esp_http_client_set_header(evt->client, "From", "user@example.com");\r
+            // esp_http_client_set_header(evt->client, "Accept", "text/html");\r
+            // esp_http_client_set_redirection(evt->client);\r
+            break;\r
+    }\r
+    return ESP_OK;\r
+}\r
+\r
+void\r
+MatrixHttpConnect(\r
+    MatrixHttpConnection * hc)\r
+{\r
+    esp_http_client_config_t config = {\r
+        .url = hc->host,\r
+        // .query = "esp",\r
+        .event_handler = _http_event_handler,\r
+        .user_data = hc,\r
+        .disable_auto_redirect = true,\r
+        .crt_bundle_attach = esp_crt_bundle_attach,\r
+    };\r
+\r
+    hc->client = esp_http_client_init(&config);\r
+\r
+    esp_http_client_set_timeout_ms(hc->client, 20000);\r
+}\r
+\r
+void\r
+MatrixHttpDisconnect(\r
+    MatrixHttpConnection * hc)\r
+{\r
+    esp_http_client_cleanup(hc->client);\r
+    hc->client = NULL;\r
+}\r
+\r
+bool\r
+MatrixHttpInit(\r
+    MatrixHttpConnection ** hc,\r
+    const char * host)\r
+{\r
+    *hc = (MatrixHttpConnection *)calloc(1, sizeof(MatrixHttpConnection));\r
+    \r
+    (*hc)->host = host;\r
+\r
+    MatrixHttpConnect(*hc);\r
+\r
+    return true;\r
+}\r
+\r
+bool\r
+MatrixHttpDeinit(\r
+    MatrixHttpConnection ** hc)\r
+{\r
+    MatrixHttpDisconnect(*hc);\r
+\r
+    free(*hc);\r
+    *hc = NULL;\r
+\r
+    return true;\r
+}\r
+\r
+bool\r
+MatrixHttpSetAccessToken(\r
+    MatrixHttpConnection * hc,\r
+    const char * accessToken)\r
+{\r
+    hc->accessToken = accessToken;\r
+\r
+    return true;\r
+}\r
+\r
+bool\r
+MatrixHttpGet(\r
+    MatrixHttpConnection * hc,\r
+    const char * url,\r
+    char * outResponseBuffer, int outResponseCap,\r
+    bool authenticated)\r
+{\r
+    static char authorizationHeader[AUTHORIZATION_HEADER_LEN];\r
+    if (authenticated)\r
+        snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,\r
+            "Bearer %s", hc->accessToken);\r
+    else\r
+        authorizationHeader[0] = '\0';\r
+\r
+    printf("GET %s%s\n", hc->host, url);\r
+\r
+    hc->data = outResponseBuffer;\r
+    hc->dataCap = outResponseCap;\r
+    hc->dataLen = 0;\r
+\r
+    static char hostAndUrl[MAX_URL_LEN];\r
+    snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);\r
+    \r
+    esp_http_client_set_url(hc->client, hostAndUrl);\r
+    esp_http_client_set_method(hc->client, HTTP_METHOD_GET);\r
+    if (authenticated)\r
+        esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);\r
+    esp_err_t err = esp_http_client_perform(hc->client);\r
+    if (err == ESP_OK) {\r
+        ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRIu64,\r
+                esp_http_client_get_status_code(hc->client),\r
+                esp_http_client_get_content_length(hc->client));\r
+    } else {\r
+        ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));\r
+    }\r
+    // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);\r
+\r
+    return true;\r
+}\r
+\r
+bool\r
+MatrixHttpPost(\r
+    MatrixHttpConnection * hc,\r
+    const char * url,\r
+    const char * requestBuffer,\r
+    char * outResponseBuffer, int outResponseCap,\r
+    bool authenticated)\r
+{\r
+    static char authorizationHeader[AUTHORIZATION_HEADER_LEN];\r
+    if (authenticated)\r
+        snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,\r
+            "Bearer %s", hc->accessToken);\r
+    else\r
+        authorizationHeader[0] = '\0';\r
+\r
+    printf("POST %s%s\n%s\n", hc->host, url, requestBuffer);\r
+\r
+    hc->data = outResponseBuffer;\r
+    hc->dataCap = outResponseCap;\r
+    hc->dataLen = 0;\r
+\r
+    static char hostAndUrl[MAX_URL_LEN];\r
+    snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);\r
+    \r
+    esp_http_client_set_url(hc->client, hostAndUrl);\r
+    esp_http_client_set_method(hc->client, HTTP_METHOD_POST);\r
+    if (authenticated)\r
+        esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);\r
+    esp_http_client_set_header(hc->client, "Content-Type", "application/json");\r
+    esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));\r
+    esp_err_t err = esp_http_client_perform(hc->client);\r
+    if (err == ESP_OK) {\r
+        ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRIu64,\r
+                esp_http_client_get_status_code(hc->client),\r
+                esp_http_client_get_content_length(hc->client));\r
+    } else {\r
+        ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));\r
+    }\r
+    // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);\r
+\r
+    return true;\r
+}\r
+\r
+bool\r
+MatrixHttpPut(\r
+    MatrixHttpConnection * hc,\r
+    const char * url,\r
+    const char * requestBuffer,\r
+    char * outResponseBuffer, int outResponseCap,\r
+    bool authenticated)\r
+{\r
+    static char authorizationHeader[AUTHORIZATION_HEADER_LEN];\r
+    if (authenticated)\r
+        snprintf(authorizationHeader, AUTHORIZATION_HEADER_LEN,\r
+            "Bearer %s", hc->accessToken);\r
+    else\r
+        authorizationHeader[0] = '\0';\r
+\r
+    printf("PUT %s%s\n%s\n", hc->host, url, requestBuffer);\r
+\r
+    hc->data = outResponseBuffer;\r
+    hc->dataCap = outResponseCap;\r
+    hc->dataLen = 0;\r
+\r
+    static char hostAndUrl[MAX_URL_LEN];\r
+    snprintf(hostAndUrl, MAX_URL_LEN, "%s%s", hc->host, url);\r
+    \r
+    esp_http_client_set_url(hc->client, hostAndUrl);\r
+    esp_http_client_set_method(hc->client, HTTP_METHOD_PUT);\r
+    if (authenticated)\r
+        esp_http_client_set_header(hc->client, "Authorization", authorizationHeader);\r
+    esp_http_client_set_header(hc->client, "Content-Type", "application/json");\r
+    esp_http_client_set_post_field(hc->client, requestBuffer, strlen(requestBuffer));\r
+    esp_err_t err = esp_http_client_perform(hc->client);\r
+    if (err == ESP_OK) {\r
+        ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %"PRIu64,\r
+                esp_http_client_get_status_code(hc->client),\r
+                esp_http_client_get_content_length(hc->client));\r
+    } else {\r
+        ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));\r
+    }\r
+    // ESP_LOG_BUFFER_HEX(TAG, hc->data, hc->dataLen);\r
+\r
+    return true;\r
+}\r