static void check_ccm_long(void) { /* This test is too big for embedded runs. Needs a streaming interface. */ #if ! (defined(CORTEX_M0) || defined(CORTEX_M3) || defined(CORTEX_M4)) /* This is example 4 from SP800-38C, to test the long AAD code path. */ uint8_t header[0x10000]; uint8_t key[16]; uint8_t tag[14]; uint8_t nonce[13]; uint8_t plain[32], cipher[32]; fill(header, sizeof header, 0x00); fill(key, sizeof key, 0x40); fill(nonce, sizeof nonce, 0x10); fill(plain, sizeof plain, 0x20); const void *expect_tag = "\xb4\xac\x6b\xec\x93\xe8\x59\x8e\x7f\x0d\xad\xbc\xea\x5b"; const void *expect_cipher = "\x69\x91\x5d\xad\x1e\x84\xc6\x37\x6a\x68\xc2\x96\x7e\x4d\xab\x61\x5a\xe0\xfd\x1f\xae\xc4\x4c\xc4\x84\x82\x85\x29\x46\x3c\xcf\x72"; cf_aes_context ctx; cf_aes_init(&ctx, key, sizeof key); cf_ccm_encrypt(&cf_aes, &ctx, plain, sizeof plain, 15 - sizeof nonce, header, sizeof header, nonce, sizeof nonce, cipher, tag, sizeof tag); TEST_CHECK(memcmp(expect_tag, tag, sizeof tag) == 0); TEST_CHECK(memcmp(expect_cipher, cipher, sizeof cipher) == 0); #endif (void) fill; }
static int aesctr_setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key, size_t key_size) { struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx; ctx->super.do_dispose = aesctr_dispose; ctx->super.do_init = aesctr_init; ctx->super.do_transform = aesctr_transform; cf_aes_init(&ctx->aes, key, key_size); return 0; }
static void test_ctr(void) { uint8_t out[16]; const void *nonce = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"; const void *key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c"; const void *inp = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"; const void *expect = "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce"; cf_aes_context aes; cf_aes_init(&aes, key, 16); cf_ctr ctr; cf_ctr_init(&ctr, &cf_aes, &aes, nonce); cf_ctr_cipher(&ctr, inp, out, 16); /* one piece */ TEST_CHECK(memcmp(expect, out, 16) == 0); cf_ctr_init(&ctr, &cf_aes, &aes, nonce); cf_ctr_cipher(&ctr, inp, out, 1); /* incremental (2 blocks) */ cf_ctr_cipher(&ctr, inp, out, 16); cf_ctr_cipher(&ctr, inp, out, 16); cf_ctr_init(&ctr, &cf_aes, &aes, nonce); cf_ctr_cipher(&ctr, inp, out, 1); /* incremental */ cf_ctr_cipher(&ctr, inp + 1, out + 1, 15); TEST_CHECK(memcmp(expect, out, 16) == 0); uint8_t decrypt[16]; cf_ctr_init(&ctr, &cf_aes, &aes, nonce); cf_ctr_cipher(&ctr, out, decrypt, 16); TEST_CHECK(memcmp(decrypt, inp, 16) == 0); /* Test we use the right number of blocks up. */ uint8_t test_nonce[16], test_inp[16]; memset(test_nonce, 0xff, 16); memset(test_inp, 0x00, 16); cf_ctr_init(&ctr, &cf_aes, &aes, test_nonce); /* Exercise cf_blockwise_xor code paths. */ for (int i = 0; i < 1024; i++) { cf_ctr_cipher(&ctr, test_inp, out, i % 16); } /* expected counter value is 1024 * 7.5 / 16 - 1: * 479 = 0x1df */ memset(test_nonce, 0, sizeof test_nonce); test_nonce[15] = 0xdf; test_nonce[14] = 0x01; TEST_CHECK(memcmp(test_nonce, ctr.nonce, 16) == 0); }
static void test_eax(void) { uint8_t cipher[2], tag[16]; /* * MSG: F7FB * KEY: 91945D3F4DCBEE0BF45EF52255F095A4 * NONCE: BECAF043B0A23D843194BA972C66DEBD * HEADER: FA3BFD4806EB53FA * CIPHER: 19DD5C4C9331049D0BDAB0277408F67967E5 */ const void *key = "\x91\x94\x5d\x3f\x4d\xcb\xee\x0b\xf4\x5e\xf5\x22\x55\xf0\x95\xa4"; const void *nonce = "\xbe\xca\xf0\x43\xb0\xa2\x3d\x84\x31\x94\xba\x97\x2c\x66\xde\xbd"; size_t nnonce = 16; const void *header = "\xfa\x3b\xfd\x48\x06\xeb\x53\xfa"; size_t nheader = 8; const void *msg = "\xf7\xfb"; size_t nmsg = 2; cf_aes_context aes; cf_aes_init(&aes, key, 16); cf_eax_encrypt(&cf_aes, &aes, msg, nmsg, header, nheader, nonce, nnonce, cipher, tag, sizeof tag); TEST_CHECK(memcmp("\x19\xdd", cipher, 2) == 0); TEST_CHECK(memcmp("\x5c\x4c\x93\x31\x04\x9d\x0b\xda\xb0\x27\x74\x08\xf6\x79\x67\xe5", tag, sizeof tag) == 0); int rc; uint8_t tmp[2]; rc = cf_eax_decrypt(&cf_aes, &aes, cipher, sizeof cipher, header, nheader, nonce, nnonce, tag, sizeof tag, tmp); TEST_CHECK(rc == 0); TEST_CHECK(memcmp(tmp, msg, nmsg) == 0); tag[0] ^= 0xff; rc = cf_eax_decrypt(&cf_aes, &aes, cipher, sizeof cipher, header, nheader, nonce, nnonce, tag, sizeof tag, tmp); TEST_CHECK(rc == 1); }
static void check_ocb(const void *key, size_t nkey, const void *header, size_t nheader, const void *plain, size_t nplain, const void *nonce, size_t nnonce, const void *expect_cipher, size_t ncipher, const void *expect_tag, size_t ntag) { uint8_t cipher[40], tag[16]; assert(ncipher == nplain); assert(ncipher <= sizeof cipher); assert(ntag <= sizeof tag); cf_aes_context ctx; cf_aes_init(&ctx, key, nkey); cf_ocb_encrypt(&cf_aes, &ctx, plain, nplain, header, nheader, nonce, nnonce, cipher, tag, ntag); TEST_CHECK(memcmp(tag, expect_tag, ntag) == 0); TEST_CHECK(memcmp(cipher, expect_cipher, ncipher) == 0); uint8_t decrypted[40]; int err; err = cf_ocb_decrypt(&cf_aes, &ctx, expect_cipher, ncipher, header, nheader, nonce, nnonce, tag, ntag, decrypted); TEST_CHECK(err == 0); TEST_CHECK(memcmp(decrypted, plain, nplain) == 0); tag[0] ^= 0xff; err = cf_ocb_decrypt(&cf_aes, &ctx, expect_cipher, ncipher, header, nheader, nonce, nnonce, tag, ntag, decrypted); TEST_CHECK(err == 1); }
static void cbcmac_vector(const void *tag_expect, size_t ntag, const void *key, size_t nkey, const void *msg, size_t nmsg) { uint8_t tag[16]; cf_aes_context aes; cf_aes_init(&aes, key, nkey); cf_cbcmac_stream cm; cf_cbcmac_stream_init(&cm, &cf_aes, &aes); cf_cbcmac_stream_update(&cm, msg, nmsg); cf_cbcmac_stream_pad_final(&cm, tag); TEST_CHECK(sizeof tag == ntag); TEST_CHECK(memcmp(tag, tag_expect, sizeof tag) == 0); }
static void check_cmac(const void *key, size_t nkey, const void *msg, size_t nmsg, const void *wanttag, size_t ntag) { uint8_t gottag[16]; TEST_CHECK(cf_aes.blocksz == ntag); cf_aes_context aes; cf_aes_init(&aes, key, nkey); cf_cmac cmac; cf_cmac_init(&cmac, &cf_aes, &aes); cf_cmac_sign(&cmac, msg, nmsg, gottag); TEST_CHECK(memcmp(gottag, wanttag, cf_aes.blocksz) == 0); }
static void check_eax(const void *key, size_t nkey, const void *msg, size_t nmsg, const void *nonce, size_t nnonce, const void *header, size_t nheader, const void *expect_cipher, const void *expect_tag, size_t ntag) { uint8_t cipher[32]; uint8_t tag[16]; assert(nmsg <= sizeof cipher); assert(ntag <= ntag); cf_aes_context aes; cf_aes_init(&aes, key, nkey); cf_eax_encrypt(&cf_aes, &aes, msg, nmsg, header, nheader, nonce, nnonce, cipher, tag, ntag); TEST_CHECK(memcmp(expect_cipher, cipher, nmsg) == 0); TEST_CHECK(memcmp(expect_tag, tag, ntag) == 0); int rc; uint8_t tmp[sizeof cipher]; rc = cf_eax_decrypt(&cf_aes, &aes, cipher, nmsg, header, nheader, nonce, nnonce, tag, ntag, tmp); TEST_CHECK(rc == 0); TEST_CHECK(memcmp(tmp, msg, nmsg) == 0); tag[0] ^= 0xff; rc = cf_eax_decrypt(&cf_aes, &aes, cipher, nmsg, header, nheader, nonce, nnonce, tag, ntag, tmp); TEST_CHECK(rc == 1); }
static void check_gcm(const void *key, size_t nkey, const void *plain, size_t nplain, const void *aad, size_t naad, const void *iv, size_t niv, const void *cipher_expect, size_t ncipher, const void *tag_expect, size_t ntag) { uint8_t plain_decrypt[64], cipher[64], tag[16]; assert(ncipher == nplain); cf_aes_context ctx; cf_aes_init(&ctx, key, nkey); cf_gcm_encrypt(&cf_aes, &ctx, plain, nplain, aad, naad, iv, niv, cipher, tag, ntag); TEST_CHECK(memcmp(tag, tag_expect, ntag) == 0); TEST_CHECK(memcmp(cipher, cipher_expect, ncipher) == 0); int err = cf_gcm_decrypt(&cf_aes, &ctx, cipher, ncipher, aad, naad, iv, niv, tag, ntag, plain_decrypt); TEST_CHECK(err == 0); TEST_CHECK(memcmp(plain_decrypt, plain, ncipher) == 0); tag[0] ^= 0xff; err = cf_gcm_decrypt(&cf_aes, &ctx, cipher, ncipher, aad, naad, iv, niv, tag, ntag, plain_decrypt); TEST_CHECK(err == 1); }
static int aead_aesgcm_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key, size_t key_size) { struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx; ctx->super.dispose_crypto = aesgcm_dispose_crypto; if (is_enc) { ctx->super.do_encrypt_init = aesgcm_encrypt_init; ctx->super.do_encrypt_update = aesgcm_encrypt_update; ctx->super.do_encrypt_final = aesgcm_encrypt_final; ctx->super.do_decrypt = NULL; } else { ctx->super.do_encrypt_init = NULL; ctx->super.do_encrypt_update = NULL; ctx->super.do_encrypt_final = NULL; ctx->super.do_decrypt = aesgcm_decrypt; } cf_aes_init(&ctx->aes, key, key_size); return 0; }
static void test_cbc(void) { uint8_t out[16]; const void *iv = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"; const void *key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c"; const void *inp = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"; const void *expect = "\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d"; cf_aes_context aes; cf_aes_init(&aes, key, 16); cf_cbc cbc; cf_cbc_init(&cbc, &cf_aes, &aes, iv); cf_cbc_encrypt(&cbc, inp, out, 1); TEST_CHECK(memcmp(out, expect, 16) == 0); uint8_t decrypt[16]; cf_cbc_init(&cbc, &cf_aes, &aes, iv); cf_cbc_decrypt(&cbc, out, decrypt, 1); TEST_CHECK(memcmp(decrypt, inp, 16) == 0); }
static void check_ocb_long(size_t nkey, const void *expect_tag, size_t ntag) { uint8_t C[22400]; uint8_t K[32]; uint8_t S[128] = { 0 }; uint8_t N[12] = { 0 }; size_t nC = 0; memset(K, 0, sizeof K); K[nkey - 1] = ntag * 8; cf_aes_context aes; cf_aes_init(&aes, K, nkey); for (size_t i = 0; i < 128; i++) { /* N = num2str(3i+1, 96) */ memset(N, 0, sizeof N); write32_be(3 * i + 1, N + 8); /* C = C || OCB-ENCRYPT(K, N, S, S) * nb. OCB-ENCRYPT(Key, Nonce, AAD, Plain) */ cf_ocb_encrypt(&cf_aes, &aes, S, i, /* plain */ S, i, /* aad */ N, sizeof N, /* nonce */ C + nC, /* cipher out */ C + nC + i, /* tag out */ ntag); nC += i + ntag; /* N = num2str(3i+2,96) */ write32_be(3 * i + 2, N + 8); /* C = C || OCB-ENCRYPT(K, N, <empty string>, S) */ cf_ocb_encrypt(&cf_aes, &aes, S, i, NULL, 0, N, sizeof N, C + nC, C + nC + i, ntag); nC += i + ntag; /* N = num2str(3i+3,96) */ write32_be(3 * i + 3, N + 8); /* C = C || OCB-ENCRYPT(K, N, S, <empty string>) */ cf_ocb_encrypt(&cf_aes, &aes, NULL, 0, S, i, N, sizeof N, NULL, C + nC, ntag); nC += ntag; } /* N = num2str(385, 96) */ write32_be(385, N + 8); /* Output : OCB-ENCRYPT(K, N, C, <empty string>) */ uint8_t result[16]; cf_ocb_encrypt(&cf_aes, &aes, NULL, 0, C, nC, N, sizeof N, NULL, result, ntag); TEST_CHECK(memcmp(result, expect_tag, ntag) == 0); }