Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2019 Philippe Reynes <philippe.reynes@softathome.com> * * Unit tests for aes functions */ #include <common.h> #include <command.h> #include <hexdump.h> #include <rand.h> #include <uboot_aes.h> #include <test/lib.h> #include <test/test.h> #include <test/ut.h> #define TEST_AES_ONE_BLOCK 0 #define TEST_AES_CBC_CHAIN 1 struct test_aes_s { int key_len; int key_exp_len; int type; int num_block; }; static struct test_aes_s test_aes[] = { { AES128_KEY_LENGTH, AES128_EXPAND_KEY_LENGTH, TEST_AES_ONE_BLOCK, 1 }, { AES128_KEY_LENGTH, AES128_EXPAND_KEY_LENGTH, TEST_AES_CBC_CHAIN, 16 }, { AES192_KEY_LENGTH, AES192_EXPAND_KEY_LENGTH, TEST_AES_ONE_BLOCK, 1 }, { AES192_KEY_LENGTH, AES192_EXPAND_KEY_LENGTH, TEST_AES_CBC_CHAIN, 16 }, { AES256_KEY_LENGTH, AES256_EXPAND_KEY_LENGTH, TEST_AES_ONE_BLOCK, 1 }, { AES256_KEY_LENGTH, AES256_EXPAND_KEY_LENGTH, TEST_AES_CBC_CHAIN, 16 }, }; static void rand_buf(u8 *buf, int size) { int i; for (i = 0; i < size; i++) buf[i] = rand() & 0xff; } static int lib_test_aes_one_block(struct unit_test_state *uts, int key_len, u8 *key_exp, u8 *iv, int num_block, u8 *nocipher, u8 *ciphered, u8 *uncipher) { aes_encrypt(key_len, nocipher, key_exp, ciphered); aes_decrypt(key_len, ciphered, key_exp, uncipher); ut_asserteq_mem(nocipher, uncipher, AES_BLOCK_LENGTH); /* corrupt the expanded key */ key_exp[0]++; aes_decrypt(key_len, ciphered, key_exp, uncipher); ut_assertf(memcmp(nocipher, uncipher, AES_BLOCK_LENGTH), "nocipher and uncipher should be different\n"); return 0; } static int lib_test_aes_cbc_chain(struct unit_test_state *uts, int key_len, u8 *key_exp, u8 *iv, int num_block, u8 *nocipher, u8 *ciphered, u8 *uncipher) { aes_cbc_encrypt_blocks(key_len, key_exp, iv, nocipher, ciphered, num_block); aes_cbc_decrypt_blocks(key_len, key_exp, iv, ciphered, uncipher, num_block); ut_asserteq_mem(nocipher, uncipher, num_block * AES_BLOCK_LENGTH); /* corrupt the expanded key */ key_exp[0]++; aes_cbc_decrypt_blocks(key_len, key_exp, iv, ciphered, uncipher, num_block); ut_assertf(memcmp(nocipher, uncipher, num_block * AES_BLOCK_LENGTH), "nocipher and uncipher should be different\n"); return 0; } static int _lib_test_aes_run(struct unit_test_state *uts, int key_len, int key_exp_len, int type, int num_block) { u8 *key, *key_exp, *iv; u8 *nocipher, *ciphered, *uncipher; int ret; /* Allocate all the buffer */ key = malloc(key_len); key_exp = malloc(key_exp_len); iv = malloc(AES_BLOCK_LENGTH); nocipher = malloc(num_block * AES_BLOCK_LENGTH); ciphered = malloc((num_block + 1) * AES_BLOCK_LENGTH); uncipher = malloc((num_block + 1) * AES_BLOCK_LENGTH); if (!key || !key_exp || !iv || !nocipher || !ciphered || !uncipher) { printf("%s: can't allocate memory\n", __func__); ret = -1; goto out; } /* Initialize all buffer */ rand_buf(key, key_len); rand_buf(iv, AES_BLOCK_LENGTH); rand_buf(nocipher, num_block * AES_BLOCK_LENGTH); memset(ciphered, 0, (num_block + 1) * AES_BLOCK_LENGTH); memset(uncipher, 0, (num_block + 1) * AES_BLOCK_LENGTH); /* Expand the key */ aes_expand_key(key, key_len, key_exp); /* Encrypt and decrypt */ switch (type) { case TEST_AES_ONE_BLOCK: ret = lib_test_aes_one_block(uts, key_len, key_exp, iv, num_block, nocipher, ciphered, uncipher); break; case TEST_AES_CBC_CHAIN: ret = lib_test_aes_cbc_chain(uts, key_len, key_exp, iv, num_block, nocipher, ciphered, uncipher); break; default: printf("%s: unknown type (type=%d)\n", __func__, type); ret = -1; }; out: /* Free all the data */ free(key); free(key_exp); free(iv); free(nocipher); free(ciphered); free(uncipher); return ret; } static int lib_test_aes_run(struct unit_test_state *uts, struct test_aes_s *test) { int key_len = test->key_len; int key_exp_len = test->key_exp_len; int type = test->type; int num_block = test->num_block; return _lib_test_aes_run(uts, key_len, key_exp_len, type, num_block); } static int lib_test_aes(struct unit_test_state *uts) { int i, ret = 0; for (i = 0; i < ARRAY_SIZE(test_aes); i++) { ret = lib_test_aes_run(uts, &test_aes[i]); if (ret) break; } return ret; } LIB_TEST(lib_test_aes, 0); |