1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stdint.h>
11 #include <string.h>
12 
13 #include <limits.h>
14 
15 /* mbedtls lib */
16 #include "mbedtls/gcm.h"
17 #include "mbedtls/cipher.h"
18 #include "mbedtls/timing.h"
19 
20 /* pal */
21 #include "test_pal_mem.h"
22 
23 /* local */
24 #include "run_integration_pal_log.h"
25 #include "run_integration_test.h"
26 #include "run_integration_helper.h"
27 
28 /************************************************************
29  *
30  * static function prototypes
31  *
32  ************************************************************/
33 static RunItError_t runIt_gcmProfiling(size_t data_len);
34 static RunItError_t runIt_gcm(void);
35 
36 /************************************************************
37  *
38  * static functions
39  *
40  ************************************************************/
41 
runIt_gcmProfiling(size_t data_len)42 static RunItError_t runIt_gcmProfiling(size_t data_len)
43 {
44 
45     RunItError_t rc = RUNIT_ERROR__OK;
46 
47 #if defined(MBEDTLS_GCM_C)
48     static const uint8_t key[] = {0xFE,0xFF,0xE9,0x92,0x86,0x65,0x73,0x1C,0x6D,0x6A,0x8F,0x94,0x67,0x30,0x83,0x08};
49     static const uint8_t iv[] = {0xCA,0xFE,0xBA,0xBE,0xFA,0xCE,0xDB,0xAD,0xDE,0xCA,0xF8,0x88};
50     static const size_t iv_len = sizeof(iv);
51     static const uint8_t additional[] = {0x3A,0xD7,0x7B,0xB4,0x0D,0x7A,0x36,0x60,0xA8,0x9E,0xCA,0xF3,0x24,0x66,0xEF,0x97};
52     static const size_t add_len = sizeof(additional);
53     static const size_t tag_len = 16;
54     static const int key_len = sizeof(key) * 8;
55 
56     RunItPtr ctxPtr;
57     mbedtls_gcm_context *pCtx = NULL;
58 
59     RunItPtr cipherPtr, plainBufPtr, tagBufPtr, ivBufPtr, addBufPtr;
60     uint8_t *pCipher = NULL, *pPlainBuf = NULL, *pTagBuf = NULL, *pIvBuf = NULL, *pAddBuf = NULL;
61     char testParam[PARAM_LEN] = { 0 };
62 
63     const char* TEST_NAME = "AES-GCM Profiling";
64     RUNIT_SUB_TEST_START(TEST_NAME);
65 
66     snprintf(testParam, PARAM_LEN - 1, "%"PRIu32"B", (uint32_t)data_len);
67 
68     ALLOC_STRUCT(mbedtls_gcm_context, ctxPtr, pCtx);
69     ALLOC(cipherPtr, pCipher, data_len);
70     ALLOC(plainBufPtr, pPlainBuf, data_len);
71     ALLOC(tagBufPtr, pTagBuf, tag_len);
72     ALLOC_AND_COPY(ivBufPtr, pIvBuf, iv, iv_len);
73     ALLOC_AND_COPY(addBufPtr, pAddBuf, additional, add_len);
74 
75 
76 
77     /***************************************************************
78      *                     ENCRYPTION                              *
79      ***************************************************************/
80 
81     RUNIT_ASSERT(runIt_buildRandomBuffer(pPlainBuf, data_len) == 0);
82 
83     RUNIT_API(mbedtls_gcm_init(pCtx));
84 
85     RUNIT_API(mbedtls_gcm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, key, key_len));
86 
87     RUNIT_ASSERT_WITH_RESULT(mbedtls_gcm_crypt_and_tag(pCtx,
88                                                        MBEDTLS_GCM_ENCRYPT,
89                                                        data_len,
90                                                        pIvBuf,
91                                                        iv_len,
92                                                        pAddBuf,
93                                                        add_len,
94                                                        pPlainBuf,
95                                                        pCipher,
96                                                        tag_len,
97                                                        pTagBuf), 0);
98 
99 bail:
100     RUNIT_API(mbedtls_gcm_free(pCtx));
101 
102     FREE_IF_NOT_NULL(ctxPtr);
103     FREE_IF_NOT_NULL(cipherPtr);
104     FREE_IF_NOT_NULL(plainBufPtr);
105     FREE_IF_NOT_NULL(tagBufPtr);
106     FREE_IF_NOT_NULL(ivBufPtr);
107     FREE_IF_NOT_NULL(addBufPtr);
108 
109     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] AAD[%"PRIu32"B]",
110                                    (uint32_t)key_len, (uint32_t)data_len, (uint32_t)add_len);
111 #endif /* defined(MBEDTLS_GCM_C) */
112     return rc;
113 
114 
115 }
116 
runIt_gcm(void)117 static RunItError_t runIt_gcm(void)
118 {
119     RunItError_t rc = RUNIT_ERROR__OK;
120 
121 #if defined(MBEDTLS_GCM_C)
122     /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_GCM.pdf */
123     static const uint8_t key[] = {0xFE,0xFF,0xE9,0x92,0x86,0x65,0x73,0x1C,0x6D,0x6A,0x8F,0x94,0x67,0x30,0x83,0x08};
124     static const uint8_t iv[] = {0xCA,0xFE,0xBA,0xBE,0xFA,0xCE,0xDB,0xAD,0xDE,0xCA,0xF8,0x88};
125     static const size_t iv_len = sizeof(iv);
126     static const uint8_t additional[] = {0x3A,0xD7,0x7B,0xB4,0x0D,0x7A,0x36,0x60,0xA8,0x9E,0xCA,0xF3,0x24,0x66,0xEF,0x97,0xF5,0xD3,0xD5,0x85,0x03,0xB9,0x69,0x9D,0xE7,0x85,0x89,0x5A,0x96,0xFD,0xBA,0xAF,0x43,0xB1,0xCD,0x7F,0x59,0x8E,0xCE,0x23,0x88,0x1B,0x00,0xE3,0xED,0x03,0x06,0x88,0x7B,0x0C,0x78,0x5E,0x27,0xE8,0xAD,0x3F,0x82,0x23,0x20,0x71,0x04,0x72,0x5D,0xD4};
127     static const size_t add_len = sizeof(additional);
128     static const uint8_t pt[] = {0xD9,0x31,0x32,0x25,0xF8,0x84,0x06,0xE5,0xA5,0x59,0x09,0xC5,0xAF,0xF5,0x26,0x9A,0x86,0xA7,0xA9,0x53,0x15,0x34,0xF7,0xDA,0x2E,0x4C,0x30,0x3D,0x8A,0x31,0x8A,0x72,0x1C,0x3C,0x0C,0x95,0x95,0x68,0x09,0x53,0x2F,0xCF,0x0E,0x24,0x49,0xA6,0xB5,0x25,0xB1,0x6A,0xED,0xF5,0xAA,0x0D,0xE6,0x57,0xBA,0x63,0x7B,0x39,0x1A,0xAF,0xD2,0x55};
129     static const size_t pt_len = sizeof(pt);
130     static const uint8_t ct[] = {0x42,0x83,0x1E,0xC2,0x21,0x77,0x74,0x24,0x4B,0x72,0x21,0xB7,0x84,0xD0,0xD4,0x9C,0xE3,0xAA,0x21,0x2F,0x2C,0x02,0xA4,0xE0,0x35,0xC1,0x7E,0x23,0x29,0xAC,0xA1,0x2E,0x21,0xD5,0x14,0xB2,0x54,0x66,0x93,0x1C,0x7D,0x8F,0x6A,0x5A,0xAC,0x84,0xAA,0x05,0x1B,0xA3,0x0B,0x39,0x6A,0x0A,0xAC,0x97,0x3D,0x58,0xE0,0x91,0x47,0x3F,0x59,0x85};
131     static const size_t ct_len = sizeof(ct);
132     static const uint8_t tag[] = {0x64,0xC0,0x23,0x29,0x04,0xAF,0x39,0x8A,0x5B,0x67,0xC1,0x0B,0x53,0xA5,0x02,0x4D};
133     static const size_t tag_len = sizeof(tag);
134     static const int key_len = sizeof(key) * 8;
135 
136     RunItPtr ctxPtr;
137     mbedtls_gcm_context *pCtx = NULL;
138 
139     RunItPtr bufPtr, cipherPtr, plainBufPtr, tagBufPtr, ivBufPtr, addBufPtr;
140     uint8_t *pBuf = NULL, *pCipher = NULL, *pPlainBuf = NULL, *pTagBuf = NULL, *pIvBuf = NULL, *pAddBuf = NULL;
141 
142     const char* TEST_NAME = "AES-GCM";
143     RUNIT_SUB_TEST_START(TEST_NAME);
144 
145     ALLOC_STRUCT(mbedtls_gcm_context, ctxPtr, pCtx);
146     ALLOC(bufPtr, pBuf, ct_len);
147     ALLOC_AND_COPY(cipherPtr, pCipher, ct, ct_len);
148     ALLOC_AND_COPY(plainBufPtr, pPlainBuf, pt, pt_len);
149     ALLOC(tagBufPtr, pTagBuf, tag_len);
150     ALLOC_AND_COPY(ivBufPtr, pIvBuf, iv, iv_len);
151     ALLOC_AND_COPY(addBufPtr, pAddBuf, additional, add_len);
152 
153     memset(pBuf, 0, sizeof(ct));
154 
155     /***************************************************************
156      *                     ENCRYPTION                              *
157      ***************************************************************/
158     RUNIT_API(mbedtls_gcm_init(pCtx));
159 
160     RUNIT_API(mbedtls_gcm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, key, key_len));
161 
162     RUNIT_ASSERT_W_PARAM("encrypt", mbedtls_gcm_crypt_and_tag(pCtx,
163                                                               MBEDTLS_GCM_ENCRYPT,
164                                                               pt_len,
165                                                               pIvBuf,
166                                                               iv_len,
167                                                               pAddBuf,
168                                                               add_len,
169                                                               pPlainBuf,
170                                                               pBuf,
171                                                               sizeof(tag),
172                                                               pTagBuf) == 0);
173 
174     RUNIT_PRINT_BUF(pBuf, ct_len, "pBuf");
175     RUNIT_PRINT_BUF(ct, ct_len, "ct");
176 
177     RUNIT_PRINT_BUF(pTagBuf, tag_len, "pTagBuf");
178     RUNIT_PRINT_BUF(tag, tag_len, "tag");
179 
180     RUNIT_ASSERT(memcmp(pBuf, ct, pt_len) == 0);
181     RUNIT_ASSERT(memcmp(pTagBuf, tag, tag_len) == 0);
182 
183     RUNIT_API(mbedtls_gcm_free(pCtx));
184 
185     /***************************************************************
186      *                     DECRYPTION                              *
187      ***************************************************************/
188     memset(pBuf, 0, sizeof(ct));
189     memcpy(pTagBuf, tag, tag_len);
190 
191     RUNIT_API(mbedtls_gcm_init(pCtx));
192 
193     RUNIT_API(mbedtls_gcm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, key, key_len));
194 
195     RUNIT_ASSERT_W_PARAM("decrypt", mbedtls_gcm_crypt_and_tag(pCtx,
196                                                               MBEDTLS_GCM_DECRYPT,
197                                                               pt_len,
198                                                               pIvBuf,
199                                                               iv_len,
200                                                               pAddBuf,
201                                                               add_len,
202                                                               pCipher,
203                                                               pBuf,
204                                                               tag_len,
205                                                               pTagBuf) == 0);
206 
207 
208     RUNIT_ASSERT(memcmp(pBuf, pt, pt_len) == 0);
209 
210     RUNIT_API(mbedtls_gcm_free(pCtx));
211 
212     /***************************************************************
213      *            ALTERNATIVE DECRYPTION API                       *
214      ***************************************************************/
215     memset(pBuf, 0, sizeof(ct));
216     memcpy(pTagBuf, tag, tag_len);
217 
218     RUNIT_API(mbedtls_gcm_init(pCtx));
219 
220     RUNIT_API(mbedtls_gcm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, key, key_len));
221 
222     RUNIT_ASSERT_API(mbedtls_gcm_auth_decrypt(pCtx,
223                                               pt_len,
224                                               pIvBuf,
225                                               iv_len,
226                                               pAddBuf,
227                                               add_len,
228                                               pTagBuf,
229                                               tag_len,
230                                               pCipher,
231                                               pBuf) == 0);
232 
233     RUNIT_ASSERT(memcmp(pBuf, pt, pt_len) == 0);
234 
235 bail:
236     RUNIT_API(mbedtls_gcm_free(pCtx));
237 
238     FREE_IF_NOT_NULL(ctxPtr);
239     FREE_IF_NOT_NULL(bufPtr);
240     FREE_IF_NOT_NULL(cipherPtr);
241     FREE_IF_NOT_NULL(plainBufPtr);
242     FREE_IF_NOT_NULL(tagBufPtr);
243     FREE_IF_NOT_NULL(ivBufPtr);
244     FREE_IF_NOT_NULL(addBufPtr);
245 
246     RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] AAD[%"PRIu32"B]",
247                                    (uint32_t)key_len, (uint32_t)pt_len, (uint32_t)add_len);
248 #endif /* defined(MBEDTLS_GCM_C) */
249     return rc;
250 
251 }
252 
253 /************************************************************
254  *
255  * public functions
256  *
257  ************************************************************/
runIt_gcmTest(void)258 RunItError_t runIt_gcmTest(void)
259 {
260     RunItError_t rc = RUNIT_ERROR__OK;
261 
262     const char* TEST_NAME = "GCM";
263     RUNIT_TEST_START(TEST_NAME);
264 
265     RUNIT_ASSERT(runIt_gcm() == RUNIT_ERROR__OK);
266     RUNIT_ASSERT(runIt_gcmProfiling(16) == RUNIT_ERROR__OK);
267     RUNIT_ASSERT(runIt_gcmProfiling(128) == RUNIT_ERROR__OK);
268     RUNIT_ASSERT(runIt_gcmProfiling(1024) == RUNIT_ERROR__OK);
269     RUNIT_ASSERT(runIt_gcmProfiling(8192) == RUNIT_ERROR__OK);
270     RUNIT_ASSERT(runIt_gcmProfiling(65535) == RUNIT_ERROR__OK);
271 
272 bail:
273 
274     RUNIT_TEST_RESULT(TEST_NAME);
275     return rc;
276 }
277