]>
Commit | Line | Data |
---|---|---|
a370ff8d MC |
1 | /* |
2 | * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | /* | |
11 | * CMAC low level APIs are deprecated for public use, but still ok for internal | |
12 | * use. | |
13 | */ | |
14 | #include "internal/deprecated.h" | |
15 | ||
16 | #include <stdio.h> | |
17 | #include <string.h> | |
18 | #include <stdlib.h> | |
19 | ||
20 | #include "internal/nelem.h" | |
21 | ||
22 | #include <openssl/cmac.h> | |
23 | #include <openssl/aes.h> | |
24 | #include <openssl/evp.h> | |
25 | ||
26 | #include "testutil.h" | |
27 | ||
28 | static const char xtskey[32] = { | |
29 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, | |
30 | 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, | |
31 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f | |
32 | }; | |
33 | ||
34 | static struct test_st { | |
35 | const char key[32]; | |
36 | int key_len; | |
37 | const unsigned char data[64]; | |
38 | int data_len; | |
39 | const char *mac; | |
40 | } test[3] = { | |
41 | { | |
42 | { | |
43 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, | |
44 | 0x0b, 0x0c, 0x0d, 0x0e, 0x0f | |
45 | }, | |
46 | 16, | |
47 | "My test data", | |
48 | 12, | |
49 | "29cec977c48f63c200bd5c4a6881b224" | |
50 | }, | |
51 | { | |
52 | { | |
53 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, | |
54 | 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, | |
55 | 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f | |
56 | }, | |
57 | 32, | |
58 | "My test data", | |
59 | 12, | |
60 | "db6493aa04e4761f473b2b453c031c9a" | |
61 | }, | |
62 | { | |
63 | { | |
64 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, | |
65 | 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, | |
66 | 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f | |
67 | }, | |
68 | 32, | |
69 | "My test data again", | |
70 | 18, | |
71 | "65c11c75ecf590badd0a5e56cbb8af60" | |
72 | }, | |
73 | }; | |
74 | ||
75 | static char *pt(unsigned char *md, unsigned int len); | |
76 | ||
77 | static int test_cmac_bad(void) | |
78 | { | |
79 | CMAC_CTX *ctx = NULL; | |
80 | int ret = 0; | |
81 | ||
82 | ctx = CMAC_CTX_new(); | |
83 | if (!TEST_ptr(ctx) | |
84 | || !TEST_false(CMAC_Init(ctx, NULL, 0, NULL, NULL)) | |
85 | || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)) | |
86 | /* Should be able to pass cipher first, and then key */ | |
87 | || !TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_128_cbc(), NULL)) | |
88 | /* Must have a key */ | |
89 | || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)) | |
90 | /* Now supply the key */ | |
91 | || !TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, NULL, NULL)) | |
92 | /* Update should now work */ | |
93 | || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) | |
94 | /* XTS is not a suitable cipher to use */ | |
95 | || !TEST_false(CMAC_Init(ctx, xtskey, sizeof(xtskey), EVP_aes_128_xts(), | |
96 | NULL)) | |
97 | || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))) | |
98 | goto err; | |
99 | ||
100 | ret = 1; | |
101 | err: | |
102 | CMAC_CTX_free(ctx); | |
103 | return ret; | |
104 | } | |
105 | ||
106 | static int test_cmac_run(void) | |
107 | { | |
108 | char *p; | |
109 | CMAC_CTX *ctx = NULL; | |
110 | unsigned char buf[AES_BLOCK_SIZE]; | |
111 | size_t len; | |
112 | int ret = 0; | |
113 | ||
114 | ctx = CMAC_CTX_new(); | |
115 | ||
116 | if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, | |
117 | EVP_aes_128_cbc(), NULL)) | |
118 | || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) | |
119 | || !TEST_true(CMAC_Final(ctx, buf, &len))) | |
120 | goto err; | |
121 | ||
122 | p = pt(buf, len); | |
123 | if (!TEST_str_eq(p, test[0].mac)) | |
124 | goto err; | |
125 | ||
126 | if (!TEST_true(CMAC_Init(ctx, test[1].key, test[1].key_len, | |
127 | EVP_aes_256_cbc(), NULL)) | |
128 | || !TEST_true(CMAC_Update(ctx, test[1].data, test[1].data_len)) | |
129 | || !TEST_true(CMAC_Final(ctx, buf, &len))) | |
130 | goto err; | |
131 | ||
132 | p = pt(buf, len); | |
133 | if (!TEST_str_eq(p, test[1].mac)) | |
134 | goto err; | |
135 | ||
136 | if (!TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL)) | |
137 | || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) | |
138 | || !TEST_true(CMAC_Final(ctx, buf, &len))) | |
139 | goto err; | |
140 | p = pt(buf, len); | |
141 | if (!TEST_str_eq(p, test[2].mac)) | |
142 | goto err; | |
143 | /* Test reusing a key */ | |
144 | if (!TEST_true(CMAC_Init(ctx, NULL, 0, NULL, NULL)) | |
145 | || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) | |
146 | || !TEST_true(CMAC_Final(ctx, buf, &len))) | |
147 | goto err; | |
148 | p = pt(buf, len); | |
149 | if (!TEST_str_eq(p, test[2].mac)) | |
150 | goto err; | |
151 | ||
152 | /* Test setting the cipher and key separately */ | |
153 | if (!TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_256_cbc(), NULL)) | |
154 | || !TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL)) | |
155 | || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) | |
156 | || !TEST_true(CMAC_Final(ctx, buf, &len))) | |
157 | goto err; | |
158 | p = pt(buf, len); | |
159 | if (!TEST_str_eq(p, test[2].mac)) | |
160 | goto err; | |
161 | ||
162 | ret = 1; | |
163 | err: | |
164 | CMAC_CTX_free(ctx); | |
165 | return ret; | |
166 | } | |
167 | ||
168 | static int test_cmac_copy(void) | |
169 | { | |
170 | char *p; | |
171 | CMAC_CTX *ctx = NULL, *ctx2 = NULL; | |
172 | unsigned char buf[AES_BLOCK_SIZE]; | |
173 | size_t len; | |
174 | int ret = 0; | |
175 | ||
176 | ctx = CMAC_CTX_new(); | |
177 | ctx2 = CMAC_CTX_new(); | |
178 | if (!TEST_ptr(ctx) || !TEST_ptr(ctx2)) | |
179 | goto err; | |
180 | ||
181 | if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, | |
182 | EVP_aes_128_cbc(), NULL)) | |
183 | || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) | |
184 | || !TEST_true(CMAC_CTX_copy(ctx2, ctx)) | |
185 | || !TEST_true(CMAC_Final(ctx2, buf, &len))) | |
186 | goto err; | |
187 | ||
188 | p = pt(buf, len); | |
189 | if (!TEST_str_eq(p, test[0].mac)) | |
190 | goto err; | |
191 | ||
192 | ret = 1; | |
193 | err: | |
194 | CMAC_CTX_free(ctx2); | |
195 | CMAC_CTX_free(ctx); | |
196 | return ret; | |
197 | } | |
198 | ||
199 | static char *pt(unsigned char *md, unsigned int len) | |
200 | { | |
201 | unsigned int i; | |
202 | static char buf[80]; | |
203 | ||
204 | for (i = 0; i < len; i++) | |
205 | sprintf(&(buf[i * 2]), "%02x", md[i]); | |
206 | return buf; | |
207 | } | |
208 | ||
209 | int setup_tests(void) | |
210 | { | |
211 | ADD_TEST(test_cmac_bad); | |
212 | ADD_TEST(test_cmac_run); | |
213 | ADD_TEST(test_cmac_copy); | |
214 | return 1; | |
215 | } | |
216 |