Add GCM tag length verification 53/84453/2
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 18 Aug 2016 14:27:52 +0000 (16:27 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 19 Aug 2016 12:10:10 +0000 (14:10 +0200)
Change-Id: If3b1c5e33d9a93a2120e8aeddfca024f05355321

api/yaca/yaca_types.h
src/encrypt.c

index 2cf7d50369fd966b0e8fff0d5d581f5485d7ce0d..857710c7834b8aeda83dbe41c6233d8d7cad7b42 100755 (executable)
@@ -478,8 +478,8 @@ typedef enum {
         *
         * Supported properties:
         * - #YACA_PROPERTY_GCM_TAG_LEN = GCM tag length\n
-        *   Supported tag lengths: @c 32, @c 64, @c 96, @c 104, @c 112, @c 120, @c 128,
-        *   (recommended 128 bits tag).\n
+        *   Supported tag lengths: @c 4, @c 8, @c 12, @c 13, @c 14, @c 15, @c 16,
+        *   (recommended 16 bytes tag).\n
         *   Set after yaca_encrypt_finalize() / yaca_seal_finalize() and before
         *   yaca_context_get_property(#YACA_PROPERTY_GCM_TAG)
         *   in encryption / seal operation. The @a value should be a size_t variable.\n
@@ -534,7 +534,7 @@ typedef enum {
         *
         * Supported properties:
         * - #YACA_PROPERTY_CCM_TAG_LEN = CCM tag length\n
-        *   Supported tag lengths: 32-128 bits in step of 16 bits (recommended 96 bits tag).\n
+        *   Supported tag lengths: 4-16 bytes in steps of 2 bytes (recommended 12 bytes tag).\n
         *   Set after yaca_encrypt_initialize() / yaca_seal_initialize() and before
         *   yaca_encrypt_update() / yaca_seal_update() in encryption / seal operation.
         *   The @a value should be a size_t variable.\n
@@ -603,14 +603,14 @@ typedef enum {
        YACA_PROPERTY_GCM_AAD,
        /** GCM Tag. Property type is a buffer (e.g. char*) */
        YACA_PROPERTY_GCM_TAG,
-       /** GCM Tag length. Property type is size_t. */
+       /** GCM Tag length in bytes. Property type is size_t. */
        YACA_PROPERTY_GCM_TAG_LEN,
 
        /** CCM Additional Authentication Data. Property type is a buffer (e.g. char*) */
        YACA_PROPERTY_CCM_AAD,
        /** CCM Tag. Property type is a buffer (e.g. char*) */
        YACA_PROPERTY_CCM_TAG,
-       /** CCM Tag length. Property type is size_t. */
+       /** CCM Tag length in bytes. Property type is size_t. */
        YACA_PROPERTY_CCM_TAG_LEN
 } yaca_property_e;
 
index 0bf6eab4a208dd8dc571f3a6a9129c988f367278..7bd94fb70bac1559441513576ca658a7f5c2ce3b 100644 (file)
@@ -201,6 +201,10 @@ static bool verify_state_change(struct yaca_encrypt_context_s *c, enum encrypt_c
        return false;
 }
 
+static const size_t VALID_GCM_TAG_LENGTHS[] = { 4, 8, 12, 13, 14, 15, 16 };
+static const size_t VALID_GCM_TAG_LENGTHS_LENGTH =
+               sizeof(VALID_GCM_TAG_LENGTHS) / sizeof(VALID_GCM_TAG_LENGTHS[0]);
+
 struct yaca_encrypt_context_s *get_encrypt_context(const yaca_context_h ctx)
 {
        if (ctx == YACA_CONTEXT_NULL)
@@ -656,8 +660,18 @@ int set_encrypt_property(yaca_context_h ctx,
                if (!verify_state_change(c, STATE_TAG_LENGTH_SET))
                        return YACA_ERROR_INVALID_PARAMETER;
 
-               c->tag_len = *(size_t*)value;
-               c->state = STATE_TAG_LENGTH_SET;
+               /* check allowed tag lengths */
+               {
+                       size_t tag_len = *(size_t*)value;
+                       for (size_t i = 0; i < VALID_GCM_TAG_LENGTHS_LENGTH; i++) {
+                               if (tag_len == VALID_GCM_TAG_LENGTHS[i]) {
+                                       c->tag_len = tag_len;
+                                       c->state = STATE_TAG_LENGTH_SET;
+                                       return YACA_ERROR_NONE;
+                               }
+                       }
+                       return YACA_ERROR_INVALID_PARAMETER;
+               }
                break;
        case YACA_PROPERTY_CCM_TAG:
                if (mode != EVP_CIPH_CCM_MODE || is_encryption_op(c->op_type))