LCOV - code coverage report
Current view: top level - sgx/src/trusted - aes_gcm.c (source / functions) Hit Total Coverage
Test: powHSM firmware Lines: 54 55 98.2 %
Date: 2025-10-30 06:27:42 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 (!ciphertext) {
      75             :         LOG("AES-GCM encrypt error: unable to allocate memory\n");
      76           0 :         goto aes_gcm_encrypt_exit;
      77             :     }
      78             : 
      79           4 :     if (!random_getrandom(iv, sizeof(iv))) {
      80             :         LOG("AES-GCM encrypt error: error generating IV\n");
      81           1 :         goto aes_gcm_encrypt_exit;
      82             :     }
      83             : 
      84             :     // Set key
      85           3 :     if (mbedtls_gcm_setkey(
      86             :             &gcm_ctx, MBEDTLS_CIPHER_ID_AES, key, key_size * 8) != 0) {
      87             :         LOG("AES-GCM encrypt error: failed to set key\n");
      88           1 :         goto aes_gcm_encrypt_exit;
      89             :     }
      90             : 
      91             :     // Encrypt
      92           2 :     if (mbedtls_gcm_crypt_and_tag(&gcm_ctx,
      93             :                                   MBEDTLS_GCM_ENCRYPT,
      94             :                                   in_size,
      95             :                                   iv,
      96             :                                   sizeof(iv),
      97             :                                   NULL,
      98             :                                   0,
      99             :                                   in,
     100             :                                   ciphertext,
     101             :                                   sizeof(tag),
     102             :                                   tag)) {
     103             :         LOG("AES-GCM encrypt error: encryption failed\n");
     104           1 :         goto aes_gcm_encrypt_exit;
     105             :     }
     106             : 
     107             :     // Output
     108           1 :     explicit_bzero(out, *out_size);
     109           1 :     memcpy(out, iv, sizeof(iv));
     110           1 :     memcpy(out + sizeof(iv), ciphertext, in_size);
     111           1 :     memcpy(out + sizeof(iv) + in_size, tag, sizeof(tag));
     112           1 :     *out_size = sizeof(iv) + in_size + sizeof(tag);
     113           1 :     retval = true;
     114             : 
     115           8 : aes_gcm_encrypt_exit:
     116           8 :     mbedtls_gcm_free(&gcm_ctx);
     117           8 :     if (ciphertext)
     118           4 :         oe_free(ciphertext);
     119           8 :     return retval;
     120             : }
     121             : 
     122           7 : bool aes_gcm_decrypt(uint8_t* key,
     123             :                      size_t key_size,
     124             :                      uint8_t* in,
     125             :                      size_t in_size,
     126             :                      uint8_t* out,
     127             :                      size_t* out_size) {
     128           7 :     bool retval = false;
     129             :     mbedtls_gcm_context gcm_ctx;
     130           7 :     mbedtls_gcm_init(&gcm_ctx);
     131           7 :     size_t cleartext_size = in_size - AES_IV_SIZE - AES_TAG_SIZE;
     132             : 
     133             :     // Sizes check
     134           7 :     if (AES_GCM_KEY_SIZE != key_size) {
     135             :         LOG("AES-GCM decrypt error: expected a %u-byte key\n",
     136             :             AES_GCM_KEY_SIZE);
     137           2 :         goto aes_gcm_decrypt_exit;
     138             :     }
     139           5 :     if (in_size <= AES_IV_SIZE + AES_TAG_SIZE) {
     140             :         LOG("AES-GCM decrypt error: input buffer too small\n");
     141           1 :         goto aes_gcm_decrypt_exit;
     142             :     }
     143           4 :     if (*out_size < cleartext_size) {
     144             :         LOG("AES-GCM decrypt error: output buffer too small\n");
     145           1 :         goto aes_gcm_decrypt_exit;
     146             :     }
     147             : 
     148             :     // Set key
     149           3 :     if (mbedtls_gcm_setkey(
     150             :             &gcm_ctx, MBEDTLS_CIPHER_ID_AES, key, key_size * 8) != 0) {
     151             :         LOG("AES-GCM decrypt error: failed to set key\n");
     152           1 :         goto aes_gcm_decrypt_exit;
     153             :     }
     154             : 
     155             :     // Decrypt
     156           2 :     if (mbedtls_gcm_auth_decrypt(&gcm_ctx,
     157             :                                  cleartext_size,
     158             :                                  in,
     159             :                                  AES_IV_SIZE,
     160             :                                  NULL,
     161             :                                  0,
     162           2 :                                  &in[AES_IV_SIZE + cleartext_size],
     163             :                                  AES_TAG_SIZE,
     164           2 :                                  &in[AES_IV_SIZE],
     165             :                                  out) != 0) {
     166             :         LOG("AES-GCM decrypt error: decryption failed\n");
     167           1 :         goto aes_gcm_decrypt_exit;
     168             :     }
     169             : 
     170             :     // Ok
     171           1 :     *out_size = cleartext_size;
     172           1 :     retval = true;
     173             : 
     174           7 : aes_gcm_decrypt_exit:
     175           7 :     mbedtls_gcm_free(&gcm_ctx);
     176           7 :     return retval;
     177             : }

Generated by: LCOV version 1.16