cmactest.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * Copyright 1995-2023 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. * CMAC low level APIs are deprecated for public use, but still ok for internal
  11. * use.
  12. */
  13. #include "internal/deprecated.h"
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include "internal/nelem.h"
  18. #include <openssl/cmac.h>
  19. #include <openssl/aes.h>
  20. #include <openssl/evp.h>
  21. #include "testutil.h"
  22. static const char xtskey[32] = {
  23. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  24. 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  25. 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
  26. };
  27. static struct test_st {
  28. const char key[32];
  29. int key_len;
  30. unsigned char data[4096];
  31. int data_len;
  32. const char *mac;
  33. } test[] = {
  34. {
  35. {
  36. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  37. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
  38. },
  39. 16,
  40. "My test data",
  41. 12,
  42. "29cec977c48f63c200bd5c4a6881b224"
  43. },
  44. {
  45. {
  46. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  47. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
  48. 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
  49. },
  50. 32,
  51. "My test data",
  52. 12,
  53. "db6493aa04e4761f473b2b453c031c9a"
  54. },
  55. {
  56. {
  57. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  58. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
  59. 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
  60. },
  61. 32,
  62. "My test data again",
  63. 18,
  64. "65c11c75ecf590badd0a5e56cbb8af60"
  65. },
  66. /* for aes-128-cbc */
  67. {
  68. {
  69. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  70. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
  71. },
  72. 16,
  73. /* repeat the string below until filling 3072 bytes */
  74. "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
  75. 3072,
  76. "35da8a02a7afce90e5b711308cee2dee"
  77. },
  78. /* for aes-192-cbc */
  79. {
  80. {
  81. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  82. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
  83. 0x16, 0x17
  84. },
  85. 24,
  86. /* repeat the string below until filling 4095 bytes */
  87. "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
  88. 4095,
  89. "59053f4e81f3593610f987adb547c5b2"
  90. },
  91. /* for aes-256-cbc */
  92. {
  93. {
  94. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  95. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
  96. 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
  97. },
  98. 32,
  99. /* repeat the string below until filling 2560 bytes */
  100. "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
  101. 2560,
  102. "9c6cf85f7f4baca99725764a0df973a9"
  103. },
  104. /* for des-ede3-cbc */
  105. {
  106. {
  107. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  108. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
  109. 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
  110. },
  111. 24,
  112. /* repeat the string below until filling 2048 bytes */
  113. "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
  114. 2048,
  115. "2c2fccc7fcc5d98a"
  116. },
  117. /* for sm4-cbc */
  118. {
  119. {
  120. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  121. 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
  122. },
  123. 16,
  124. /* repeat the string below until filling 2049 bytes */
  125. "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#",
  126. 2049,
  127. "c9a9cbc82a3b2d96074e386fce1216f2"
  128. },
  129. };
  130. static char *pt(unsigned char *md, unsigned int len);
  131. static int test_cmac_bad(void)
  132. {
  133. CMAC_CTX *ctx = NULL;
  134. int ret = 0;
  135. ctx = CMAC_CTX_new();
  136. if (!TEST_ptr(ctx)
  137. || !TEST_false(CMAC_Init(ctx, NULL, 0, NULL, NULL))
  138. || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))
  139. /* Should be able to pass cipher first, and then key */
  140. || !TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_128_cbc(), NULL))
  141. /* Must have a key */
  142. || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))
  143. /* Now supply the key */
  144. || !TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, NULL, NULL))
  145. /* Update should now work */
  146. || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
  147. /* XTS is not a suitable cipher to use */
  148. || !TEST_false(CMAC_Init(ctx, xtskey, sizeof(xtskey), EVP_aes_128_xts(),
  149. NULL))
  150. || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)))
  151. goto err;
  152. ret = 1;
  153. err:
  154. CMAC_CTX_free(ctx);
  155. return ret;
  156. }
  157. static int test_cmac_run(void)
  158. {
  159. char *p;
  160. CMAC_CTX *ctx = NULL;
  161. unsigned char buf[AES_BLOCK_SIZE];
  162. size_t len;
  163. int ret = 0;
  164. size_t case_idx = 0;
  165. ctx = CMAC_CTX_new();
  166. /* Construct input data, fill repeatedly until reaching data length */
  167. for (case_idx = 0; case_idx < OSSL_NELEM(test); case_idx++) {
  168. size_t str_len = strlen((char *)test[case_idx].data);
  169. size_t fill_len = test[case_idx].data_len - str_len;
  170. size_t fill_idx = str_len;
  171. while (fill_len > 0) {
  172. if (fill_len > str_len) {
  173. memcpy(&test[case_idx].data[fill_idx], test[case_idx].data, str_len);
  174. fill_len -= str_len;
  175. fill_idx += str_len;
  176. } else {
  177. memcpy(&test[case_idx].data[fill_idx], test[case_idx].data, fill_len);
  178. fill_len = 0;
  179. }
  180. }
  181. }
  182. if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len,
  183. EVP_aes_128_cbc(), NULL))
  184. || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
  185. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  186. goto err;
  187. p = pt(buf, len);
  188. if (!TEST_str_eq(p, test[0].mac))
  189. goto err;
  190. if (!TEST_true(CMAC_Init(ctx, test[1].key, test[1].key_len,
  191. EVP_aes_256_cbc(), NULL))
  192. || !TEST_true(CMAC_Update(ctx, test[1].data, test[1].data_len))
  193. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  194. goto err;
  195. p = pt(buf, len);
  196. if (!TEST_str_eq(p, test[1].mac))
  197. goto err;
  198. if (!TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL))
  199. || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
  200. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  201. goto err;
  202. p = pt(buf, len);
  203. if (!TEST_str_eq(p, test[2].mac))
  204. goto err;
  205. /* Test reusing a key */
  206. if (!TEST_true(CMAC_Init(ctx, NULL, 0, NULL, NULL))
  207. || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
  208. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  209. goto err;
  210. p = pt(buf, len);
  211. if (!TEST_str_eq(p, test[2].mac))
  212. goto err;
  213. /* Test setting the cipher and key separately */
  214. if (!TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_256_cbc(), NULL))
  215. || !TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL))
  216. || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len))
  217. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  218. goto err;
  219. p = pt(buf, len);
  220. if (!TEST_str_eq(p, test[2].mac))
  221. goto err;
  222. /* Test data length is greater than 1 block length */
  223. if (!TEST_true(CMAC_Init(ctx, test[3].key, test[3].key_len,
  224. EVP_aes_128_cbc(), NULL))
  225. || !TEST_true(CMAC_Update(ctx, test[3].data, test[3].data_len))
  226. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  227. goto err;
  228. p = pt(buf, len);
  229. if (!TEST_str_eq(p, test[3].mac))
  230. goto err;
  231. if (!TEST_true(CMAC_Init(ctx, test[4].key, test[4].key_len,
  232. EVP_aes_192_cbc(), NULL))
  233. || !TEST_true(CMAC_Update(ctx, test[4].data, test[4].data_len))
  234. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  235. goto err;
  236. p = pt(buf, len);
  237. if (!TEST_str_eq(p, test[4].mac))
  238. goto err;
  239. if (!TEST_true(CMAC_Init(ctx, test[5].key, test[5].key_len,
  240. EVP_aes_256_cbc(), NULL))
  241. || !TEST_true(CMAC_Update(ctx, test[5].data, test[5].data_len))
  242. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  243. goto err;
  244. p = pt(buf, len);
  245. if (!TEST_str_eq(p, test[5].mac))
  246. goto err;
  247. #ifndef OPENSSL_NO_DES
  248. if (!TEST_true(CMAC_Init(ctx, test[6].key, test[6].key_len,
  249. EVP_des_ede3_cbc(), NULL))
  250. || !TEST_true(CMAC_Update(ctx, test[6].data, test[6].data_len))
  251. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  252. goto err;
  253. p = pt(buf, len);
  254. if (!TEST_str_eq(p, test[6].mac))
  255. goto err;
  256. #endif
  257. #ifndef OPENSSL_NO_SM4
  258. if (!TEST_true(CMAC_Init(ctx, test[7].key, test[7].key_len,
  259. EVP_sm4_cbc(), NULL))
  260. || !TEST_true(CMAC_Update(ctx, test[7].data, test[7].data_len))
  261. || !TEST_true(CMAC_Final(ctx, buf, &len)))
  262. goto err;
  263. p = pt(buf, len);
  264. if (!TEST_str_eq(p, test[7].mac))
  265. goto err;
  266. #endif
  267. ret = 1;
  268. err:
  269. CMAC_CTX_free(ctx);
  270. return ret;
  271. }
  272. static int test_cmac_copy(void)
  273. {
  274. char *p;
  275. CMAC_CTX *ctx = NULL, *ctx2 = NULL;
  276. unsigned char buf[AES_BLOCK_SIZE];
  277. size_t len;
  278. int ret = 0;
  279. ctx = CMAC_CTX_new();
  280. ctx2 = CMAC_CTX_new();
  281. if (!TEST_ptr(ctx) || !TEST_ptr(ctx2))
  282. goto err;
  283. if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len,
  284. EVP_aes_128_cbc(), NULL))
  285. || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len))
  286. || !TEST_true(CMAC_CTX_copy(ctx2, ctx))
  287. || !TEST_true(CMAC_Final(ctx2, buf, &len)))
  288. goto err;
  289. p = pt(buf, len);
  290. if (!TEST_str_eq(p, test[0].mac))
  291. goto err;
  292. ret = 1;
  293. err:
  294. CMAC_CTX_free(ctx2);
  295. CMAC_CTX_free(ctx);
  296. return ret;
  297. }
  298. static char *pt(unsigned char *md, unsigned int len)
  299. {
  300. unsigned int i;
  301. static char buf[80];
  302. for (i = 0; i < len; i++)
  303. sprintf(&(buf[i * 2]), "%02x", md[i]);
  304. return buf;
  305. }
  306. int setup_tests(void)
  307. {
  308. ADD_TEST(test_cmac_bad);
  309. ADD_TEST(test_cmac_run);
  310. ADD_TEST(test_cmac_copy);
  311. return 1;
  312. }