LCOV - code coverage report
Current view: top level - sgx/src/trusted - aes_gcm.c (source / functions) Hit Total Coverage
Test: powHSM firmware Lines: 53 53 100.0 %
Date: 2025-09-08 13:01:11 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /**
       2             :  * The MIT License (MIT)
       3             :  *
       4             :  * Copyright (c) 2021 RSK Labs Ltd
       5             :  *
       6             :  * Permission is hereby granted, free of charge, to any person obtaining a copy
       7             :  * of this software and associated documentation files (the "Software"), to
       8             :  * deal in the Software without restriction, including without limitation the
       9             :  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
      10             :  * sell copies of the Software, and to permit persons to whom the Software is
      11             :  * furnished to do so, subject to the following conditions:
      12             :  *
      13             :  * The above copyright notice and this permission notice shall be included in
      14             :  * all copies or substantial portions of the Software.
      15             :  *
      16             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      17             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      18             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      19             :  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      20             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      21             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      22             :  * IN THE SOFTWARE.
      23             :  */
      24             : 
      25             : #include <stdlib.h>
      26             : #include <stdbool.h>
      27             : #include <stdint.h>
      28             : #include <string.h>
      29             : #include "hal/log.h"
      30             : #include "random.h"
      31             : #include <openenclave/corelibc/stdlib.h>
      32             : #include <mbedtls/gcm.h>
      33             : 
      34             : #define AES_GCM_KEY_SIZE 32 // AES-256
      35             : #define AES_IV_SIZE 12      // Recommended IV size for GCM
      36             : #define AES_TAG_SIZE 16     // Authentication tag size
      37             : 
      38           3 : size_t aes_gcm_get_encrypted_size(size_t cleartext_size) {
      39           3 :     if (cleartext_size + AES_IV_SIZE + AES_TAG_SIZE < cleartext_size)
      40           1 :         return 0; // Overflow
      41           2 :     return cleartext_size + AES_IV_SIZE + AES_TAG_SIZE;
      42             : }
      43             : 
      44           8 : bool aes_gcm_encrypt(uint8_t* key,
      45             :                      size_t key_size,
      46             :                      uint8_t* in,
      47             :                      size_t in_size,
      48             :                      uint8_t* out,
      49             :                      size_t* out_size) {
      50           8 :     bool retval = false;
      51             :     mbedtls_gcm_context gcm_ctx;
      52           8 :     mbedtls_gcm_init(&gcm_ctx);
      53             :     uint8_t iv[AES_IV_SIZE];
      54             :     uint8_t tag[AES_TAG_SIZE];
      55           8 :     uint8_t* ciphertext = NULL;
      56             : 
      57             :     // Sizes check
      58           8 :     if (AES_GCM_KEY_SIZE != key_size) {
      59             :         LOG("AES-GCM encrypt error: expected a %u-byte key\n",
      60             :             AES_GCM_KEY_SIZE);
      61           2 :         goto aes_gcm_encrypt_exit;
      62             :     }
      63           6 :     if (in_size == 0) {
      64             :         LOG("AES-GCM encrypt error: input buffer too small\n");
      65           1 :         goto aes_gcm_encrypt_exit;
      66             :     }
      67           5 :     if (*out_size < in_size + sizeof(iv) + sizeof(tag)) {
      68             :         LOG("AES-GCM encrypt error: output buffer too small\n");
      69           1 :         goto aes_gcm_encrypt_exit;
      70             :     }
      71             : 
      72             :     // Init buffers
      73           4 :     ciphertext = oe_malloc(in_size);
      74           4 :     if (!random_getrandom(iv, sizeof(iv))) {
      75             :         LOG("AES-GCM encrypt error: error generating IV\n");
      76           1 :         goto aes_gcm_encrypt_exit;
      77             :     }
      78             : 
      79             :     // Set key
      80           3 :     if (mbedtls_gcm_setkey(
      81             :             &gcm_ctx, MBEDTLS_CIPHER_ID_AES, key, key_size * 8) != 0) {
      82             :         LOG("AES-GCM encrypt error: failed to set key\n");
      83           1 :         goto aes_gcm_encrypt_exit;
      84             :     }
      85             : 
      86             :     // Encrypt
      87           2 :     if (mbedtls_gcm_crypt_and_tag(&gcm_ctx,
      88             :                                   MBEDTLS_GCM_ENCRYPT,
      89             :                                   in_size,
      90             :                                   iv,
      91             :                                   sizeof(iv),
      92             :                                   NULL,
      93             :                                   0,
      94             :                                   in,
      95             :                                   ciphertext,
      96             :                                   sizeof(tag),
      97             :                                   tag)) {
      98             :         LOG("AES-GCM encrypt error: encryption failed\n");
      99           1 :         goto aes_gcm_encrypt_exit;
     100             :     }
     101             : 
     102             :     // Output
     103           1 :     explicit_bzero(out, *out_size);
     104           1 :     memcpy(out, iv, sizeof(iv));
     105           1 :     memcpy(out + sizeof(iv), ciphertext, in_size);
     106           1 :     memcpy(out + sizeof(iv) + in_size, tag, sizeof(tag));
     107           1 :     *out_size = sizeof(iv) + in_size + sizeof(tag);
     108           1 :     retval = true;
     109             : 
     110           8 : aes_gcm_encrypt_exit:
     111           8 :     mbedtls_gcm_free(&gcm_ctx);
     112           8 :     if (ciphertext)
     113           4 :         oe_free(ciphertext);
     114           8 :     return retval;
     115             : }
     116             : 
     117           7 : bool aes_gcm_decrypt(uint8_t* key,
     118             :                      size_t key_size,
     119             :                      uint8_t* in,
     120             :                      size_t in_size,
     121             :                      uint8_t* out,
     122             :                      size_t* out_size) {
     123           7 :     bool retval = false;
     124             :     mbedtls_gcm_context gcm_ctx;
     125           7 :     mbedtls_gcm_init(&gcm_ctx);
     126           7 :     size_t cleartext_size = in_size - AES_IV_SIZE - AES_TAG_SIZE;
     127             : 
     128             :     // Sizes check
     129           7 :     if (AES_GCM_KEY_SIZE != key_size) {
     130             :         LOG("AES-GCM decrypt error: expected a %u-byte key\n",
     131             :             AES_GCM_KEY_SIZE);
     132           2 :         goto aes_gcm_decrypt_exit;
     133             :     }
     134           5 :     if (in_size <= AES_IV_SIZE + AES_TAG_SIZE) {
     135             :         LOG("AES-GCM decrypt error: input buffer too small\n");
     136           1 :         goto aes_gcm_decrypt_exit;
     137             :     }
     138           4 :     if (*out_size < cleartext_size) {
     139             :         LOG("AES-GCM decrypt error: output buffer too small\n");
     140           1 :         goto aes_gcm_decrypt_exit;
     141             :     }
     142             : 
     143             :     // Set key
     144           3 :     if (mbedtls_gcm_setkey(
     145             :             &gcm_ctx, MBEDTLS_CIPHER_ID_AES, key, key_size * 8) != 0) {
     146             :         LOG("AES-GCM decrypt error: failed to set key\n");
     147           1 :         goto aes_gcm_decrypt_exit;
     148             :     }
     149             : 
     150             :     // Decrypt
     151           2 :     if (mbedtls_gcm_auth_decrypt(&gcm_ctx,
     152             :                                  cleartext_size,
     153             :                                  in,
     154             :                                  AES_IV_SIZE,
     155             :                                  NULL,
     156             :                                  0,
     157           2 :                                  &in[AES_IV_SIZE + cleartext_size],
     158             :                                  AES_TAG_SIZE,
     159           2 :                                  &in[AES_IV_SIZE],
     160             :                                  out) != 0) {
     161             :         LOG("AES-GCM decrypt error: decryption failed\n");
     162           1 :         goto aes_gcm_decrypt_exit;
     163             :     }
     164             : 
     165             :     // Ok
     166           1 :     *out_size = cleartext_size;
     167           1 :     retval = true;
     168             : 
     169           7 : aes_gcm_decrypt_exit:
     170           7 :     mbedtls_gcm_free(&gcm_ctx);
     171           7 :     return retval;
     172             : }

Generated by: LCOV version 1.16