diff options
author | Yicheng Li <yichengli@chromium.org> | 2019-10-30 16:42:32 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-18 21:30:05 +0000 |
commit | 95735a121f869fbe1165357ba3e5e2f7cc220fe4 (patch) | |
tree | 232f50cbba9cf749007c20e0093131160b87e9d9 /test | |
parent | 40f05646ea791216ab894949a6408850be68a58b (diff) | |
download | chrome-ec-95735a121f869fbe1165357ba3e5e2f7cc220fe4.tar.gz |
aes: add test to make sure aes-gcm encryption/decryption are in-place
Current AES_GCM encryption/decryption implementation supports using
the same buffer both as input and output buffer. Add test so that
we'll notice if this ever changes.
BRANCH=nocturne
BUG=b:142089587
TEST=make -j buildall
Change-Id: I550493343b26d1b1928640f462dd040a66886b95
Signed-off-by: Yicheng Li <yichengli@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1892111
Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'test')
-rw-r--r-- | test/aes.c | 175 |
1 files changed, 161 insertions, 14 deletions
diff --git a/test/aes.c b/test/aes.c index ca11d9ef61..ddc0c03833 100644 --- a/test/aes.c +++ b/test/aes.c @@ -1,4 +1,6 @@ /* Copyright 2018 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,30 +26,175 @@ /* Temporary buffer, to avoid using too much stack space. */ static uint8_t tmp[512]; -static int test_aes_gcm_raw(const uint8_t *key, int key_size, - const uint8_t *plaintext, const uint8_t *ciphertext, int plaintext_size, - const uint8_t *nonce, int nonce_size, - const uint8_t *tag, int tag_size) { - - uint8_t *out = tmp; +/* + * Do encryption, put result in |result|, and compare with |ciphertext|. + */ +static int test_aes_gcm_encrypt(uint8_t *result, + const uint8_t *key, + int key_size, + const uint8_t *plaintext, + const uint8_t *ciphertext, + int plaintext_size, + const uint8_t *nonce, + int nonce_size, + const uint8_t *tag, + int tag_size) +{ static AES_KEY aes_key; static GCM128_CONTEXT ctx; - TEST_ASSERT(plaintext_size <= sizeof(tmp)); - TEST_ASSERT(AES_set_encrypt_key(key, 8 * key_size, &aes_key) == 0); - CRYPTO_gcm128_init(&ctx, &aes_key, (block128_f)AES_encrypt, 0); + CRYPTO_gcm128_init(&ctx, &aes_key, (block128_f) AES_encrypt, 0); CRYPTO_gcm128_setiv(&ctx, &aes_key, nonce, nonce_size); - CRYPTO_gcm128_encrypt(&ctx, &aes_key, plaintext, out, plaintext_size); + TEST_ASSERT(CRYPTO_gcm128_encrypt(&ctx, &aes_key, plaintext, result, + plaintext_size)); TEST_ASSERT(CRYPTO_gcm128_finish(&ctx, tag, tag_size)); - TEST_ASSERT_ARRAY_EQ(ciphertext, out, plaintext_size); + TEST_ASSERT_ARRAY_EQ(ciphertext, result, plaintext_size); + return EC_SUCCESS; +} + +/* + * Do decryption, put result in |result|, and compare with |plaintext|. + */ +static int test_aes_gcm_decrypt(uint8_t *result, + const uint8_t *key, + int key_size, + const uint8_t *plaintext, + const uint8_t *ciphertext, + int plaintext_size, + const uint8_t *nonce, + int nonce_size, + const uint8_t *tag, + int tag_size) +{ + static AES_KEY aes_key; + static GCM128_CONTEXT ctx; + + TEST_ASSERT(AES_set_encrypt_key(key, 8 * key_size, &aes_key) == 0); + + CRYPTO_gcm128_init(&ctx, &aes_key, (block128_f) AES_encrypt, 0); CRYPTO_gcm128_setiv(&ctx, &aes_key, nonce, nonce_size); - memset(out, 0, plaintext_size); - CRYPTO_gcm128_decrypt(&ctx, &aes_key, ciphertext, out, plaintext_size); + TEST_ASSERT(CRYPTO_gcm128_decrypt(&ctx, &aes_key, ciphertext, result, + plaintext_size)); TEST_ASSERT(CRYPTO_gcm128_finish(&ctx, tag, tag_size)); - TEST_ASSERT_ARRAY_EQ(plaintext, out, plaintext_size); + TEST_ASSERT_ARRAY_EQ(plaintext, result, plaintext_size); + + return EC_SUCCESS; +} + +static int test_aes_gcm_raw_inplace(const uint8_t *key, + int key_size, + const uint8_t *plaintext, + const uint8_t *ciphertext, + int plaintext_size, + const uint8_t *nonce, + int nonce_size, + const uint8_t *tag, + int tag_size) +{ + + /* + * Make copies that will be clobbered during in-place encryption or + * decryption. + */ + uint8_t plaintext_copy[plaintext_size]; + uint8_t ciphertext_copy[plaintext_size]; + + memcpy(plaintext_copy, plaintext, plaintext_size); + memcpy(ciphertext_copy, ciphertext, plaintext_size); + + TEST_ASSERT(test_aes_gcm_encrypt(plaintext_copy, + key, + key_size, + plaintext_copy, + ciphertext, + plaintext_size, + nonce, + nonce_size, + tag, + tag_size) == EC_SUCCESS); + + TEST_ASSERT(test_aes_gcm_decrypt(ciphertext_copy, + key, + key_size, + plaintext, + ciphertext_copy, + plaintext_size, + nonce, + nonce_size, + tag, + tag_size) == EC_SUCCESS); + + return EC_SUCCESS; +} + +static int test_aes_gcm_raw_non_inplace(const uint8_t *key, + int key_size, + const uint8_t *plaintext, + const uint8_t *ciphertext, + int plaintext_size, + const uint8_t *nonce, + int nonce_size, + const uint8_t *tag, + int tag_size) +{ + TEST_ASSERT(test_aes_gcm_encrypt(tmp, + key, + key_size, + plaintext, + ciphertext, + plaintext_size, + nonce, + nonce_size, + tag, + tag_size) == EC_SUCCESS); + + TEST_ASSERT(test_aes_gcm_decrypt(tmp, + key, + key_size, + plaintext, + ciphertext, + plaintext_size, + nonce, + nonce_size, + tag, + tag_size) == EC_SUCCESS); + + return EC_SUCCESS; +} + +static int test_aes_gcm_raw(const uint8_t *key, + int key_size, + const uint8_t *plaintext, + const uint8_t *ciphertext, + int plaintext_size, + const uint8_t *nonce, + int nonce_size, + const uint8_t *tag, + int tag_size) +{ + TEST_ASSERT(plaintext_size <= sizeof(tmp)); + + TEST_ASSERT(test_aes_gcm_raw_non_inplace(key, + key_size, + plaintext, + ciphertext, + plaintext_size, + nonce, + nonce_size, + tag, + tag_size) == EC_SUCCESS); + TEST_ASSERT(test_aes_gcm_raw_inplace(key, + key_size, + plaintext, + ciphertext, + plaintext_size, + nonce, + nonce_size, + tag, + tag_size) == EC_SUCCESS); return EC_SUCCESS; } |