Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2022 DMTF. All rights reserved.
4 : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : **/
6 :
7 : /** @file
8 : * AEAD (AES-GCM) Wrapper Implementation.
9 : *
10 : * RFC 5116 - An Interface and Algorithms for Authenticated Encryption
11 : * NIST SP800-38d - Cipher Modes of Operation: Galois / Counter Mode(GCM) and GMAC
12 : **/
13 :
14 : #include "internal_crypt_lib.h"
15 : #include <mbedtls/gcm.h>
16 :
17 : /**
18 : * Performs AEAD AES-GCM authenticated encryption on a data buffer and additional authenticated data (AAD).
19 : *
20 : * iv_size must be 12, otherwise false is returned.
21 : * key_size must be 16, 24 or 32, otherwise false is returned.
22 : * tag_size must be 12, 13, 14, 15, 16, otherwise false is returned.
23 : *
24 : * @param[in] key Pointer to the encryption key.
25 : * @param[in] key_size size of the encryption key in bytes.
26 : * @param[in] iv Pointer to the IV value.
27 : * @param[in] iv_size size of the IV value in bytes.
28 : * @param[in] a_data Pointer to the additional authenticated data (AAD).
29 : * @param[in] a_data_size size of the additional authenticated data (AAD) in bytes.
30 : * @param[in] data_in Pointer to the input data buffer to be encrypted.
31 : * @param[in] data_in_size size of the input data buffer in bytes.
32 : * @param[out] tag_out Pointer to a buffer that receives the authentication tag output.
33 : * @param[in] tag_size size of the authentication tag in bytes.
34 : * @param[out] data_out Pointer to a buffer that receives the encryption output.
35 : * @param[out] data_out_size size of the output data buffer in bytes.
36 : *
37 : * @retval true AEAD AES-GCM authenticated encryption succeeded.
38 : * @retval false AEAD AES-GCM authenticated encryption failed.
39 : *
40 : **/
41 467 : bool libspdm_aead_aes_gcm_encrypt(const uint8_t *key, size_t key_size,
42 : const uint8_t *iv, size_t iv_size,
43 : const uint8_t *a_data, size_t a_data_size,
44 : const uint8_t *data_in, size_t data_in_size,
45 : uint8_t *tag_out, size_t tag_size,
46 : uint8_t *data_out, size_t *data_out_size)
47 : {
48 : mbedtls_gcm_context ctx;
49 : int ret;
50 :
51 467 : if (data_in_size > INT_MAX) {
52 0 : return false;
53 : }
54 467 : if (a_data_size > INT_MAX) {
55 0 : return false;
56 : }
57 467 : if (iv_size != 12) {
58 0 : return false;
59 : }
60 467 : switch (key_size) {
61 467 : case 16:
62 : case 24:
63 : case 32:
64 467 : break;
65 0 : default:
66 0 : return false;
67 : }
68 467 : if ((tag_size != 12) && (tag_size != 13) && (tag_size != 14) &&
69 467 : (tag_size != 15) && (tag_size != 16)) {
70 0 : return false;
71 : }
72 467 : if (data_out_size != NULL) {
73 467 : if ((*data_out_size > INT_MAX) ||
74 467 : (*data_out_size < data_in_size)) {
75 0 : return false;
76 : }
77 : }
78 :
79 467 : mbedtls_gcm_init(&ctx);
80 :
81 467 : ret = mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key,
82 : (uint32_t)(key_size * 8));
83 467 : if (ret != 0) {
84 0 : return false;
85 : }
86 :
87 467 : ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT,
88 467 : (uint32_t)data_in_size, iv,
89 467 : (uint32_t)iv_size, a_data,
90 467 : (uint32_t)a_data_size, data_in, data_out,
91 : tag_size, tag_out);
92 467 : mbedtls_gcm_free(&ctx);
93 467 : if (ret != 0) {
94 0 : return false;
95 : }
96 467 : if (data_out_size != NULL) {
97 467 : *data_out_size = data_in_size;
98 : }
99 :
100 467 : return true;
101 : }
102 :
103 : /**
104 : * Performs AEAD AES-GCM authenticated decryption on a data buffer and additional authenticated data (AAD).
105 : *
106 : * iv_size must be 12, otherwise false is returned.
107 : * key_size must be 16, 24 or 32, otherwise false is returned.
108 : * tag_size must be 12, 13, 14, 15, 16, otherwise false is returned.
109 : * If additional authenticated data verification fails, false is returned.
110 : *
111 : * @param[in] key Pointer to the encryption key.
112 : * @param[in] key_size size of the encryption key in bytes.
113 : * @param[in] iv Pointer to the IV value.
114 : * @param[in] iv_size size of the IV value in bytes.
115 : * @param[in] a_data Pointer to the additional authenticated data (AAD).
116 : * @param[in] a_data_size size of the additional authenticated data (AAD) in bytes.
117 : * @param[in] data_in Pointer to the input data buffer to be decrypted.
118 : * @param[in] data_in_size size of the input data buffer in bytes.
119 : * @param[in] tag Pointer to a buffer that contains the authentication tag.
120 : * @param[in] tag_size size of the authentication tag in bytes.
121 : * @param[out] data_out Pointer to a buffer that receives the decryption output.
122 : * @param[out] data_out_size size of the output data buffer in bytes.
123 : *
124 : * @retval true AEAD AES-GCM authenticated decryption succeeded.
125 : * @retval false AEAD AES-GCM authenticated decryption failed.
126 : *
127 : **/
128 328 : bool libspdm_aead_aes_gcm_decrypt(const uint8_t *key, size_t key_size,
129 : const uint8_t *iv, size_t iv_size,
130 : const uint8_t *a_data, size_t a_data_size,
131 : const uint8_t *data_in, size_t data_in_size,
132 : const uint8_t *tag, size_t tag_size,
133 : uint8_t *data_out, size_t *data_out_size)
134 : {
135 : mbedtls_gcm_context ctx;
136 : int ret;
137 :
138 328 : if (data_in_size > INT_MAX) {
139 0 : return false;
140 : }
141 328 : if (a_data_size > INT_MAX) {
142 0 : return false;
143 : }
144 328 : if (iv_size != 12) {
145 0 : return false;
146 : }
147 328 : switch (key_size) {
148 328 : case 16:
149 : case 24:
150 : case 32:
151 328 : break;
152 0 : default:
153 0 : return false;
154 : }
155 328 : if ((tag_size != 12) && (tag_size != 13) && (tag_size != 14) &&
156 328 : (tag_size != 15) && (tag_size != 16)) {
157 0 : return false;
158 : }
159 328 : if (data_out_size != NULL) {
160 328 : if ((*data_out_size > INT_MAX) ||
161 328 : (*data_out_size < data_in_size)) {
162 0 : return false;
163 : }
164 : }
165 :
166 328 : mbedtls_gcm_init(&ctx);
167 :
168 328 : ret = mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key,
169 : (uint32_t)(key_size * 8));
170 328 : if (ret != 0) {
171 0 : return false;
172 : }
173 :
174 328 : ret = mbedtls_gcm_auth_decrypt(&ctx, (uint32_t)data_in_size, iv,
175 328 : (uint32_t)iv_size, a_data,
176 328 : (uint32_t)a_data_size, tag,
177 328 : (uint32_t)tag_size, data_in, data_out);
178 328 : mbedtls_gcm_free(&ctx);
179 328 : if (ret != 0) {
180 27 : return false;
181 : }
182 301 : if (data_out_size != NULL) {
183 301 : *data_out_size = data_in_size;
184 : }
185 :
186 301 : return true;
187 : }
|