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