blob: 86f7fb9929e580b060d9f37bf6b3b5f43c894a51 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/gcm.h"
Gilles Peskine36dd93e2021-04-13 13:02:03 +02003
4/* Use the multipart interface to process the encrypted data in two parts
5 * and check that the output matches the expected output.
6 * The context must have been set up with the key. */
7static int check_multipart( mbedtls_gcm_context *ctx,
8 int mode,
9 const data_t *iv,
10 const data_t *add,
11 const data_t *input,
12 const data_t *expected_output,
13 const data_t *tag,
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +020014 size_t n1,
15 size_t n1_add)
Gilles Peskine36dd93e2021-04-13 13:02:03 +020016{
17 int ok = 0;
18 uint8_t *output = NULL;
19 size_t n2 = input->len - n1;
Mateusz Starzyk658f4fd2021-05-26 14:26:48 +020020 size_t n2_add = add->len - n1_add;
Gilles Peskinea56c4482021-04-15 17:22:35 +020021 size_t olen;
Gilles Peskine36dd93e2021-04-13 13:02:03 +020022
23 /* Sanity checks on the test data */
24 TEST_ASSERT( n1 <= input->len );
Mateusz Starzyk658f4fd2021-05-26 14:26:48 +020025 TEST_ASSERT( n1_add <= add->len );
Gilles Peskine36dd93e2021-04-13 13:02:03 +020026 TEST_EQUAL( input->len, expected_output->len );
27
28 TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
Gilles Peskine295fc132021-04-15 18:32:23 +020029 iv->x, iv->len ) );
Mateusz Starzyk658f4fd2021-05-26 14:26:48 +020030 TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x, n1_add ) );
31 TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x + n1_add, n2_add ) );
Gilles Peskine36dd93e2021-04-13 13:02:03 +020032
33 /* Allocate a tight buffer for each update call. This way, if the function
34 * tries to write beyond the advertised required buffer size, this will
35 * count as an overflow for memory sanitizers and static checkers. */
36 ASSERT_ALLOC( output, n1 );
Gilles Peskinea56c4482021-04-15 17:22:35 +020037 olen = 0xdeadbeef;
38 TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x, n1, output, n1, &olen ) );
39 TEST_EQUAL( n1, olen );
40 ASSERT_COMPARE( output, olen, expected_output->x, n1 );
Gilles Peskine36dd93e2021-04-13 13:02:03 +020041 mbedtls_free( output );
42 output = NULL;
43
44 ASSERT_ALLOC( output, n2 );
Gilles Peskinea56c4482021-04-15 17:22:35 +020045 olen = 0xdeadbeef;
46 TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x + n1, n2, output, n2, &olen ) );
47 TEST_EQUAL( n2, olen );
48 ASSERT_COMPARE( output, olen, expected_output->x + n1, n2 );
Gilles Peskine36dd93e2021-04-13 13:02:03 +020049 mbedtls_free( output );
50 output = NULL;
51
52 ASSERT_ALLOC( output, tag->len );
Gilles Peskine9461e452021-04-15 16:48:32 +020053 TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, output, tag->len ) );
Gilles Peskine36dd93e2021-04-13 13:02:03 +020054 ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
55 mbedtls_free( output );
56 output = NULL;
57
58 ok = 1;
59exit:
60 mbedtls_free( output );
61 return( ok );
62}
63
Mateusz Starzykfc606222021-06-16 11:04:07 +020064static void check_cipher_with_empty_ad( mbedtls_gcm_context *ctx,
65 int mode,
66 const data_t *iv,
67 const data_t *input,
68 const data_t *expected_output,
69 const data_t *tag,
70 size_t ad_update_count)
71{
72 size_t n;
73 uint8_t *output = NULL;
74 size_t olen;
75
76 /* Sanity checks on the test data */
77 TEST_EQUAL( input->len, expected_output->len );
78
79 TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
80 iv->x, iv->len ) );
81
82 for( n = 0; n < ad_update_count; n += 1 )
83 {
84 TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, NULL, 0 ) );
85 }
86
87 /* Allocate a tight buffer for each update call. This way, if the function
88 * tries to write beyond the advertised required buffer size, this will
89 * count as an overflow for memory sanitizers and static checkers. */
90 ASSERT_ALLOC( output, input->len );
91 olen = 0xdeadbeef;
92 TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x, input->len, output, input->len, &olen ) );
93 TEST_EQUAL( input->len, olen );
94 ASSERT_COMPARE( output, olen, expected_output->x, input->len );
95 mbedtls_free( output );
96 output = NULL;
97
98 ASSERT_ALLOC( output, tag->len );
99 TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, output, tag->len ) );
100 ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
101
102exit:
103 mbedtls_free( output );
104}
105
106static void check_empty_cipher_with_ad( mbedtls_gcm_context *ctx,
107 int mode,
108 const data_t *iv,
109 const data_t *add,
110 const data_t *tag,
111 size_t cipher_update_count)
112{
113 size_t olen;
114 size_t n;
115 uint8_t* output_tag = NULL;
116
117 TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode, iv->x, iv->len ) );
118 TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x, add->len ) );
119
120 for( n = 0; n < cipher_update_count; n += 1 )
121 {
122 olen = 0xdeadbeef;
123 TEST_EQUAL( 0, mbedtls_gcm_update( ctx, NULL, 0, NULL, 0, &olen ) );
124 TEST_EQUAL( 0, olen );
125 }
126
127 ASSERT_ALLOC( output_tag, tag->len );
128 TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, output_tag, tag->len ) );
129 ASSERT_COMPARE( output_tag, tag->len, tag->x, tag->len );
130
131exit:
132 mbedtls_free( output_tag );
133}
134
Paul Bakker33b43f12013-08-20 11:48:36 +0200135/* END_HEADER */
Paul Bakker89e80c92012-03-20 13:50:09 +0000136
Paul Bakker33b43f12013-08-20 11:48:36 +0200137/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138 * depends_on:MBEDTLS_GCM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200139 * END_DEPENDENCIES
140 */
Paul Bakker89e80c92012-03-20 13:50:09 +0000141
Paul Bakker33b43f12013-08-20 11:48:36 +0200142/* BEGIN_CASE */
Ron Eldor5a21fd62016-12-16 16:15:56 +0200143void gcm_bad_parameters( int cipher_id, int direction,
Azim Khan5fcca462018-06-29 11:05:32 +0100144 data_t *key_str, data_t *src_str,
145 data_t *iv_str, data_t *add_str,
Ron Eldor5a21fd62016-12-16 16:15:56 +0200146 int tag_len_bits, int gcm_result )
147{
Ron Eldor5a21fd62016-12-16 16:15:56 +0200148 unsigned char output[128];
149 unsigned char tag_output[16];
150 mbedtls_gcm_context ctx;
Azim Khan317efe82017-08-02 17:33:54 +0100151 size_t tag_len = tag_len_bits / 8;
Ron Eldor5a21fd62016-12-16 16:15:56 +0200152
153 mbedtls_gcm_init( &ctx );
154
Ron Eldor5a21fd62016-12-16 16:15:56 +0200155 memset( output, 0x00, sizeof( output ) );
156 memset( tag_output, 0x00, sizeof( tag_output ) );
Darryl Green11999bb2018-03-13 15:22:58 +0000157
Azim Khan317efe82017-08-02 17:33:54 +0100158 TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
159 TEST_ASSERT( mbedtls_gcm_crypt_and_tag( &ctx, direction, src_str->len, iv_str->x, iv_str->len,
160 add_str->x, add_str->len, src_str->x, output, tag_len, tag_output ) == gcm_result );
Ron Eldor5a21fd62016-12-16 16:15:56 +0200161
162exit:
163 mbedtls_gcm_free( &ctx );
164}
165/* END_CASE */
166
167/* BEGIN_CASE */
Azim Khan5fcca462018-06-29 11:05:32 +0100168void gcm_encrypt_and_tag( int cipher_id, data_t * key_str,
169 data_t * src_str, data_t * iv_str,
Ronald Cronac6ae352020-06-26 14:33:03 +0200170 data_t * add_str, data_t * dst,
171 int tag_len_bits, data_t * tag,
Azim Khand30ca132017-06-09 04:32:58 +0100172 int init_result )
Paul Bakker89e80c92012-03-20 13:50:09 +0000173{
Paul Bakker89e80c92012-03-20 13:50:09 +0000174 unsigned char output[128];
175 unsigned char tag_output[16];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176 mbedtls_gcm_context ctx;
Azim Khanf1aaec92017-05-30 14:23:15 +0100177 size_t tag_len = tag_len_bits / 8;
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200178 size_t n1;
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200179 size_t n1_add;
Paul Bakker89e80c92012-03-20 13:50:09 +0000180
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200181 mbedtls_gcm_init( &ctx );
182
Paul Bakker89e80c92012-03-20 13:50:09 +0000183 memset(output, 0x00, 128);
184 memset(tag_output, 0x00, 16);
185
Paul Bakker89e80c92012-03-20 13:50:09 +0000186
Azim Khand30ca132017-06-09 04:32:58 +0100187 TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200188 if( init_result == 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000189 {
Azim Khand30ca132017-06-09 04:32:58 +0100190 TEST_ASSERT( mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x, iv_str->len, add_str->x, add_str->len, src_str->x, output, tag_len, tag_output ) == 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000191
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200192 ASSERT_COMPARE( output, src_str->len, dst->x, dst->len );
193 ASSERT_COMPARE( tag_output, tag_len, tag->x, tag->len );
194
Gilles Peskine58fc2722021-04-13 15:58:27 +0200195 for( n1 = 0; n1 <= src_str->len; n1 += 1 )
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200196 {
197 mbedtls_test_set_step( n1 );
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200198
199 for( n1_add = 0; n1_add <= add_str->len; n1_add += 1 )
200 {
201 mbedtls_test_set_step( n1_add );
202 if( !check_multipart( &ctx, MBEDTLS_GCM_ENCRYPT,
203 iv_str, add_str, src_str,
204 dst, tag,
205 n1, n1_add ) )
206 goto exit;
207 }
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200208 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000209 }
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200210
Paul Bakkerbd51b262014-07-10 15:26:12 +0200211exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212 mbedtls_gcm_free( &ctx );
Paul Bakker89e80c92012-03-20 13:50:09 +0000213}
Paul Bakker33b43f12013-08-20 11:48:36 +0200214/* END_CASE */
Paul Bakker89e80c92012-03-20 13:50:09 +0000215
Paul Bakker33b43f12013-08-20 11:48:36 +0200216/* BEGIN_CASE */
Azim Khan5fcca462018-06-29 11:05:32 +0100217void gcm_decrypt_and_verify( int cipher_id, data_t * key_str,
218 data_t * src_str, data_t * iv_str,
219 data_t * add_str, int tag_len_bits,
220 data_t * tag_str, char * result,
221 data_t * pt_result, int init_result )
Paul Bakker89e80c92012-03-20 13:50:09 +0000222{
Paul Bakker89e80c92012-03-20 13:50:09 +0000223 unsigned char output[128];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224 mbedtls_gcm_context ctx;
Paul Bakker89e80c92012-03-20 13:50:09 +0000225 int ret;
Azim Khanf1aaec92017-05-30 14:23:15 +0100226 size_t tag_len = tag_len_bits / 8;
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200227 size_t n1;
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200228 size_t n1_add;
Paul Bakker89e80c92012-03-20 13:50:09 +0000229
Manuel Pégourié-Gonnardc34e8dd2015-04-28 21:42:17 +0200230 mbedtls_gcm_init( &ctx );
231
Paul Bakker89e80c92012-03-20 13:50:09 +0000232 memset(output, 0x00, 128);
233
Paul Bakker89e80c92012-03-20 13:50:09 +0000234
Azim Khand30ca132017-06-09 04:32:58 +0100235 TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200236 if( init_result == 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000237 {
Azim Khand30ca132017-06-09 04:32:58 +0100238 ret = mbedtls_gcm_auth_decrypt( &ctx, src_str->len, iv_str->x, iv_str->len, add_str->x, add_str->len, tag_str->x, tag_len, src_str->x, output );
Paul Bakker89e80c92012-03-20 13:50:09 +0000239
Azim Khan46c9b1f2017-05-31 20:46:35 +0100240 if( strcmp( "FAIL", result ) == 0 )
Paul Bakker89e80c92012-03-20 13:50:09 +0000241 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242 TEST_ASSERT( ret == MBEDTLS_ERR_GCM_AUTH_FAILED );
Paul Bakker89e80c92012-03-20 13:50:09 +0000243 }
244 else
245 {
Manuel Pégourié-Gonnardf7ce67f2013-09-03 20:17:35 +0200246 TEST_ASSERT( ret == 0 );
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200247 ASSERT_COMPARE( output, src_str->len, pt_result->x, pt_result->len );
Paul Bakker89e80c92012-03-20 13:50:09 +0000248
Gilles Peskine58fc2722021-04-13 15:58:27 +0200249 for( n1 = 0; n1 <= src_str->len; n1 += 1 )
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200250 {
251 mbedtls_test_set_step( n1 );
Mateusz Starzykaf4ecdd2021-06-15 15:29:48 +0200252 for( n1_add = 0; n1_add <= add_str->len; n1_add += 1 )
253 {
254 mbedtls_test_set_step( n1_add );
255 if( !check_multipart( &ctx, MBEDTLS_GCM_DECRYPT,
256 iv_str, add_str, src_str,
257 pt_result, tag_str,
258 n1, n1_add ) )
259 goto exit;
260 }
Gilles Peskine36dd93e2021-04-13 13:02:03 +0200261 }
Paul Bakker89e80c92012-03-20 13:50:09 +0000262 }
263 }
Manuel Pégourié-Gonnard4fe92002013-09-13 13:45:58 +0200264
Paul Bakkerbd51b262014-07-10 15:26:12 +0200265exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266 mbedtls_gcm_free( &ctx );
Paul Bakker89e80c92012-03-20 13:50:09 +0000267}
Paul Bakker33b43f12013-08-20 11:48:36 +0200268/* END_CASE */
Paul Bakker89e80c92012-03-20 13:50:09 +0000269
Mateusz Starzykfc606222021-06-16 11:04:07 +0200270/* BEGIN_CASE */
271void gcm_decrypt_and_verify_empty_cipher( int cipher_id,
272 data_t * key_str,
273 data_t * iv_str,
274 data_t * add_str,
275 data_t * tag_str,
276 int cipher_update_calls,
277 int init_result )
278{
279 mbedtls_gcm_context ctx;
280
281 mbedtls_gcm_init( &ctx );
282
283 TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
284 if( init_result == 0 )
285 {
286 check_empty_cipher_with_ad( &ctx, MBEDTLS_GCM_DECRYPT,
287 iv_str, add_str, tag_str,
288 cipher_update_calls );
289 }
290
291 mbedtls_gcm_free( &ctx );
292}
293/* END_CASE */
294
295/* BEGIN_CASE */
296void gcm_decrypt_and_verify_empty_ad( int cipher_id,
297 data_t * key_str,
298 data_t * iv_str,
299 data_t * src_str,
300 data_t * tag_str,
301 data_t * pt_result,
302 int ad_update_calls,
303 int init_result )
304{
305 mbedtls_gcm_context ctx;
306
307 mbedtls_gcm_init( &ctx );
308
309 TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
310 if( init_result == 0 )
311 {
312 check_cipher_with_empty_ad( &ctx, MBEDTLS_GCM_DECRYPT,
313 iv_str, src_str, pt_result, tag_str,
314 ad_update_calls );
315 }
316
317 mbedtls_gcm_free( &ctx );
318}
319/* END_CASE */
320
321/* BEGIN_CASE */
322void gcm_encrypt_and_tag_empty_cipher( int cipher_id,
323 data_t * key_str,
324 data_t * iv_str,
325 data_t * add_str,
326 data_t * tag_str,
327 int cipher_update_calls,
328 int init_result )
329{
330 mbedtls_gcm_context ctx;
331
332 mbedtls_gcm_init( &ctx );
333
334 TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
335 if( init_result == 0 )
336 {
337 check_empty_cipher_with_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
338 iv_str, add_str, tag_str,
339 cipher_update_calls );
340 }
341
342exit:
343 mbedtls_gcm_free( &ctx );
344}
345/* END_CASE */
346
347/* BEGIN_CASE */
348void gcm_encrypt_and_tag_empty_ad( int cipher_id,
349 data_t * key_str,
350 data_t * iv_str,
351 data_t * src_str,
352 data_t * dst,
353 data_t * tag_str,
354 int ad_update_calls,
355 int init_result )
356{
357 mbedtls_gcm_context ctx;
358
359 mbedtls_gcm_init( &ctx );
360
361 TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
362 if( init_result == 0 )
363 {
364 check_cipher_with_empty_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
365 iv_str, src_str, dst, tag_str,
366 ad_update_calls );
367 }
368
369exit:
370 mbedtls_gcm_free( &ctx );
371}
372/* END_CASE */
373
TRodziewicz062f3532021-05-25 15:15:57 +0200374/* BEGIN_CASE depends_on:NOT_DEFINED */
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500375void gcm_invalid_param( )
376{
377 mbedtls_gcm_context ctx;
378 unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
379 mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
Ronald Cron875b5fb2021-05-21 08:50:00 +0200380 int invalid_bitlen = 1;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500381
382 mbedtls_gcm_init( &ctx );
383
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500384 /* mbedtls_gcm_setkey */
Ronald Cron875b5fb2021-05-21 08:50:00 +0200385 TEST_EQUAL(
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500386 MBEDTLS_ERR_GCM_BAD_INPUT,
387 mbedtls_gcm_setkey( &ctx, valid_cipher, valid_buffer, invalid_bitlen ) );
388
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500389exit:
390 mbedtls_gcm_free( &ctx );
391}
392/* END_CASE */
393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +0100395void gcm_selftest( )
Paul Bakker89e80c92012-03-20 13:50:09 +0000396{
Andres AG93012e82016-09-09 09:10:28 +0100397 TEST_ASSERT( mbedtls_gcm_self_test( 1 ) == 0 );
Paul Bakker89e80c92012-03-20 13:50:09 +0000398}
Paul Bakker33b43f12013-08-20 11:48:36 +0200399/* END_CASE */