Skip to content

Commit 29630cc

Browse files
mrfuchsjhedberg
authored andcommitted
samples: crypto: Add AES-GCM sample
Add sample for AES Galois/Counter Mode (GCM) of operation with a MACsec GCM-AES test vector. Also improve existing code by declaring expected ciphertext arrays as constant. Signed-off-by: Markus Fuchs <[email protected]>
1 parent ad8f011 commit 29630cc

File tree

3 files changed

+126
-5
lines changed

3 files changed

+126
-5
lines changed

samples/drivers/crypto/prj_mtls_shim.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CONFIG_MBEDTLS_BUILTIN=y
55
CONFIG_MBEDTLS_CFG_FILE="config-tls-generic.h"
66
CONFIG_MBEDTLS_HEAP_SIZE=512
77
CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y
8+
CONFIG_MBEDTLS_CIPHER_MODE_GCM_ENABLED=y
89
CONFIG_MAIN_STACK_SIZE=4096
910

1011
CONFIG_CRYPTO=y

samples/drivers/crypto/sample.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ tests:
1818
- ".*: CBC Mode"
1919
- ".*: CTR Mode"
2020
- ".*: CCM Mode"
21+
- ".*: GCM Mode"
2122
sample.drivers.crypto.mbedtls.micro:
2223
tags: crypto
2324
harness_config:
@@ -27,6 +28,7 @@ tests:
2728
- ".*: CBC Mode"
2829
- ".*: CTR Mode"
2930
- ".*: CCM Mode"
31+
- ".*: GCM Mode"
3032
sample.drivers.crypto.stm32:
3133
tags: crypto
3234
platform_whitelist: mikroe_mini_m4_for_stm32

samples/drivers/crypto/src/main.c

Lines changed: 123 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static u8_t plaintext[64] = {
4343

4444
u32_t cap_flags;
4545

46-
static void print_buffer_comparison(u8_t *wanted_result,
46+
static void print_buffer_comparison(const u8_t *wanted_result,
4747
u8_t *result, size_t length)
4848
{
4949
int i, j;
@@ -113,7 +113,7 @@ void ecb_mode(struct device *dev)
113113
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
114114
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
115115
};
116-
u8_t ecb_ciphertext[16] = {
116+
const u8_t ecb_ciphertext[16] = {
117117
0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30,
118118
0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A
119119
};
@@ -188,7 +188,7 @@ void ecb_mode(struct device *dev)
188188
cipher_free_session(dev, &ini);
189189
}
190190

191-
static u8_t cbc_ciphertext[80] = {
191+
static const u8_t cbc_ciphertext[80] = {
192192
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
193193
0x0c, 0x0d, 0x0e, 0x0f, 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
194194
0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, 0x50, 0x86, 0xcb, 0x9b,
@@ -276,7 +276,7 @@ void cbc_mode(struct device *dev)
276276
cipher_free_session(dev, &ini);
277277
}
278278

279-
static u8_t ctr_ciphertext[64] = {
279+
static const u8_t ctr_ciphertext[64] = {
280280
0x22, 0xe5, 0x2f, 0xb1, 0x77, 0xd8, 0x65, 0xb2,
281281
0xf7, 0xc6, 0xb5, 0x12, 0x69, 0x2d, 0x11, 0x4d,
282282
0xed, 0x6c, 0x1c, 0x72, 0x25, 0xda, 0xf6, 0xa2,
@@ -381,7 +381,7 @@ static u8_t ccm_data[23] = {
381381
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
382382
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
383383
};
384-
static u8_t ccm_expected[31] = {
384+
static const u8_t ccm_expected[31] = {
385385
0x58, 0x8c, 0x97, 0x9a, 0x61, 0xc6, 0x63, 0xd2, 0xf0, 0x66, 0xd0, 0xc2,
386386
0xc0, 0xf9, 0x89, 0x80, 0x6d, 0x5f, 0x6b, 0x61, 0xda, 0xc3, 0x84, 0x17,
387387
0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0
@@ -477,6 +477,123 @@ void ccm_mode(struct device *dev)
477477
cipher_free_session(dev, &ini);
478478
}
479479

480+
/* MACsec GCM-AES test vector 2.4.1 */
481+
static u8_t gcm_key[16] = {
482+
0x07, 0x1b, 0x11, 0x3b, 0x0c, 0xa7, 0x43, 0xfe, 0xcc, 0xcf, 0x3d, 0x05,
483+
0x1f, 0x73, 0x73, 0x82
484+
};
485+
static u8_t gcm_nonce[12] = {
486+
0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d, 0x00, 0x01, 0x76, 0xd4, 0x57, 0xed
487+
};
488+
static u8_t gcm_hdr[20] = {
489+
0xe2, 0x01, 0x06, 0xd7, 0xcd, 0x0d, 0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d,
490+
0x88, 0xe5, 0x4c, 0x2a, 0x76, 0xd4, 0x57, 0xed
491+
};
492+
static u8_t gcm_data[42] = {
493+
0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
494+
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
495+
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
496+
0x31, 0x32, 0x33, 0x34, 0x00, 0x04
497+
};
498+
static const u8_t gcm_expected[58] = {
499+
0x13, 0xb4, 0xc7, 0x2b, 0x38, 0x9d, 0xc5, 0x01, 0x8e, 0x72, 0xa1, 0x71,
500+
0xdd, 0x85, 0xa5, 0xd3, 0x75, 0x22, 0x74, 0xd3, 0xa0, 0x19, 0xfb, 0xca,
501+
0xed, 0x09, 0xa4, 0x25, 0xcd, 0x9b, 0x2e, 0x1c, 0x9b, 0x72, 0xee, 0xe7,
502+
0xc9, 0xde, 0x7d, 0x52, 0xb3, 0xf3,
503+
0xd6, 0xa5, 0x28, 0x4f, 0x4a, 0x6d, 0x3f, 0xe2, 0x2a, 0x5d, 0x6c, 0x2b,
504+
0x96, 0x04, 0x94, 0xc3
505+
};
506+
507+
void gcm_mode(struct device *dev)
508+
{
509+
u8_t encrypted[60] = {0};
510+
u8_t decrypted[44] = {0};
511+
struct cipher_ctx ini = {
512+
.keylen = sizeof(gcm_key),
513+
.key.bit_stream = gcm_key,
514+
.mode_params.gcm_info = {
515+
.nonce_len = sizeof(gcm_nonce),
516+
.tag_len = 16,
517+
},
518+
.flags = cap_flags,
519+
};
520+
struct cipher_pkt encrypt = {
521+
.in_buf = gcm_data,
522+
.in_len = sizeof(gcm_data),
523+
.out_buf_max = sizeof(encrypted),
524+
.out_buf = encrypted,
525+
};
526+
struct cipher_aead_pkt gcm_op = {
527+
.ad = gcm_hdr,
528+
.ad_len = sizeof(gcm_hdr),
529+
.pkt = &encrypt,
530+
/* TinyCrypt always puts the tag at the end of the ciphered
531+
* text, but other library such as mbedtls might be more
532+
* flexible and can take a different buffer for it. So to
533+
* make sure test passes on all backends: enforcing the tag
534+
* buffer to be after the ciphered text.
535+
*/
536+
.tag = encrypted + sizeof(gcm_data),
537+
};
538+
struct cipher_pkt decrypt = {
539+
.in_buf = encrypted,
540+
.in_len = sizeof(gcm_data),
541+
.out_buf = decrypted,
542+
.out_buf_max = sizeof(decrypted),
543+
};
544+
545+
if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
546+
CRYPTO_CIPHER_MODE_GCM,
547+
CRYPTO_CIPHER_OP_ENCRYPT)) {
548+
return;
549+
}
550+
551+
gcm_op.pkt = &encrypt;
552+
if (cipher_gcm_op(&ini, &gcm_op, gcm_nonce)) {
553+
LOG_ERR("GCM mode ENCRYPT - Failed");
554+
goto out;
555+
}
556+
557+
LOG_INF("Output length (encryption): %d", encrypt.out_len);
558+
559+
if (memcmp(encrypt.out_buf, gcm_expected, sizeof(gcm_expected))) {
560+
LOG_ERR("GCM mode ENCRYPT - Mismatch between expected "
561+
"and returned cipher text");
562+
print_buffer_comparison(gcm_expected,
563+
encrypt.out_buf, sizeof(gcm_expected));
564+
goto out;
565+
}
566+
567+
LOG_INF("GCM mode ENCRYPT - Match");
568+
cipher_free_session(dev, &ini);
569+
570+
if (cipher_begin_session(dev, &ini, CRYPTO_CIPHER_ALGO_AES,
571+
CRYPTO_CIPHER_MODE_GCM,
572+
CRYPTO_CIPHER_OP_DECRYPT)) {
573+
return;
574+
}
575+
576+
gcm_op.pkt = &decrypt;
577+
if (cipher_gcm_op(&ini, &gcm_op, gcm_nonce)) {
578+
LOG_ERR("GCM mode DECRYPT - Failed");
579+
goto out;
580+
}
581+
582+
LOG_INF("Output length (decryption): %d", decrypt.out_len);
583+
584+
if (memcmp(decrypt.out_buf, gcm_data, sizeof(gcm_data))) {
585+
LOG_ERR("GCM mode DECRYPT - Mismatch between plaintext "
586+
"and decrypted cipher text");
587+
print_buffer_comparison(gcm_data,
588+
decrypt.out_buf, sizeof(gcm_data));
589+
goto out;
590+
}
591+
592+
LOG_INF("GCM mode DECRYPT - Match");
593+
out:
594+
cipher_free_session(dev, &ini);
595+
}
596+
480597
struct mode_test {
481598
const char *mode;
482599
void (*mode_func)(struct device *dev);
@@ -490,6 +607,7 @@ void main(void)
490607
{ .mode = "CBC Mode", .mode_func = cbc_mode },
491608
{ .mode = "CTR Mode", .mode_func = ctr_mode },
492609
{ .mode = "CCM Mode", .mode_func = ccm_mode },
610+
{ .mode = "GCM Mode", .mode_func = gcm_mode },
493611
{ },
494612
};
495613
int i;

0 commit comments

Comments
 (0)