You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

245 lines
8.4 KiB

  1. /* Copyright (c) 2014, Google Inc.
  2. *
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  10. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  12. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
  14. #include <stdint.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <openssl/crypto.h>
  18. #include <openssl/digest.h>
  19. #include <openssl/err.h>
  20. #include <openssl/md4.h>
  21. #include <openssl/md5.h>
  22. #include <openssl/sha.h>
  23. typedef struct {
  24. /* md_func is the digest to test. */
  25. const EVP_MD *(*md_func)(void);
  26. /* one_shot_func is the convenience one-shot version of the
  27. * digest. */
  28. uint8_t *(*one_shot_func)(const uint8_t *, size_t, uint8_t *);
  29. /* input is a NUL-terminated string to hash. */
  30. const char *input;
  31. /* repeat is the number of times to repeat input. */
  32. size_t repeat;
  33. /* expected_hex is the expected digest in hexadecimal. */
  34. const char *expected_hex;
  35. } TEST_VECTOR;
  36. static const TEST_VECTOR kTestVectors[] = {
  37. /* MD4 tests, from RFC 1320. (crypto/md4 does not provide a
  38. * one-shot MD4 function.) */
  39. { &EVP_md4, NULL, "", 1, "31d6cfe0d16ae931b73c59d7e0c089c0" },
  40. { &EVP_md4, NULL, "a", 1, "bde52cb31de33e46245e05fbdbd6fb24" },
  41. { &EVP_md4, NULL, "abc", 1, "a448017aaf21d8525fc10ae87aa6729d" },
  42. { &EVP_md4, NULL, "message digest", 1,
  43. "d9130a8164549fe818874806e1c7014b" },
  44. { &EVP_md4, NULL, "abcdefghijklmnopqrstuvwxyz", 1,
  45. "d79e1c308aa5bbcdeea8ed63df412da9" },
  46. { &EVP_md4, NULL,
  47. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
  48. "043f8582f241db351ce627e153e7f0e4" },
  49. { &EVP_md4, NULL, "1234567890", 8, "e33b4ddc9c38f2199c3e7b164fcc0536" },
  50. /* MD5 tests, from RFC 1321. */
  51. { &EVP_md5, &MD5, "", 1, "d41d8cd98f00b204e9800998ecf8427e" },
  52. { &EVP_md5, &MD5, "a", 1, "0cc175b9c0f1b6a831c399e269772661" },
  53. { &EVP_md5, &MD5, "abc", 1, "900150983cd24fb0d6963f7d28e17f72" },
  54. { &EVP_md5, &MD5, "message digest", 1, "f96b697d7cb7938d525a2f31aaf161d0" },
  55. { &EVP_md5, &MD5, "abcdefghijklmnopqrstuvwxyz", 1,
  56. "c3fcd3d76192e4007dfb496cca67e13b" },
  57. { &EVP_md5, &MD5,
  58. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 1,
  59. "d174ab98d277d9f5a5611c2c9f419d9f" },
  60. { &EVP_md5, &MD5, "1234567890", 8, "57edf4a22be3c955ac49da2e2107b67a" },
  61. /* SHA-1 tests, from RFC 3174. */
  62. { &EVP_sha1, &SHA1, "abc", 1, "a9993e364706816aba3e25717850c26c9cd0d89d" },
  63. { &EVP_sha1, &SHA1,
  64. "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
  65. "84983e441c3bd26ebaae4aa1f95129e5e54670f1" },
  66. { &EVP_sha1, &SHA1, "a", 1000000,
  67. "34aa973cd4c4daa4f61eeb2bdbad27316534016f" },
  68. { &EVP_sha1, &SHA1,
  69. "0123456701234567012345670123456701234567012345670123456701234567", 10,
  70. "dea356a2cddd90c7a7ecedc5ebb563934f460452" },
  71. /* SHA-224 tests, from RFC 3874. */
  72. { &EVP_sha224, &SHA224, "abc", 1,
  73. "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7" },
  74. { &EVP_sha224, &SHA224,
  75. "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
  76. "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525" },
  77. { &EVP_sha224, &SHA224,
  78. "a", 1000000,
  79. "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67" },
  80. /* SHA-256 tests, from NIST. */
  81. { &EVP_sha256, &SHA256, "abc", 1,
  82. "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" },
  83. { &EVP_sha256, &SHA256,
  84. "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 1,
  85. "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" },
  86. /* SHA-384 tests, from NIST. */
  87. { &EVP_sha384, &SHA384, "abc", 1,
  88. "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"
  89. "8086072ba1e7cc2358baeca134c825a7" },
  90. { &EVP_sha384, &SHA384,
  91. "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
  92. "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
  93. "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"
  94. "fcc7c71a557e2db966c3e9fa91746039" },
  95. /* SHA-512 tests, from NIST. */
  96. { &EVP_sha512, &SHA512, "abc", 1,
  97. "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
  98. "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" },
  99. { &EVP_sha512, &SHA512,
  100. "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
  101. "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 1,
  102. "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
  103. "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" },
  104. /* MD5-SHA1 tests. */
  105. { &EVP_md5_sha1, NULL, "abc", 1,
  106. "900150983cd24fb0d6963f7d28e17f72a9993e364706816aba3e25717850c26c9cd0d89d" },
  107. };
  108. static int compare_digest(const TEST_VECTOR *test,
  109. const uint8_t *digest,
  110. size_t digest_len) {
  111. static const char kHexTable[] = "0123456789abcdef";
  112. size_t i;
  113. char digest_hex[2*EVP_MAX_MD_SIZE + 1];
  114. for (i = 0; i < digest_len; i++) {
  115. digest_hex[2*i] = kHexTable[digest[i] >> 4];
  116. digest_hex[2*i + 1] = kHexTable[digest[i] & 0xf];
  117. }
  118. digest_hex[2*digest_len] = '\0';
  119. if (strcmp(digest_hex, test->expected_hex) != 0) {
  120. fprintf(stderr, "%s(\"%s\" * %d) = %s; want %s\n",
  121. EVP_MD_name(test->md_func()), test->input, (int)test->repeat,
  122. digest_hex, test->expected_hex);
  123. return 0;
  124. }
  125. return 1;
  126. }
  127. static int test_digest(const TEST_VECTOR *test) {
  128. int ret = 0;
  129. EVP_MD_CTX ctx;
  130. size_t i;
  131. uint8_t digest[EVP_MAX_MD_SIZE];
  132. unsigned digest_len;
  133. EVP_MD_CTX_init(&ctx);
  134. /* Test the input provided. */
  135. if (!EVP_DigestInit_ex(&ctx, test->md_func(), NULL)) {
  136. fprintf(stderr, "EVP_DigestInit_ex failed\n");
  137. goto done;
  138. }
  139. for (i = 0; i < test->repeat; i++) {
  140. if (!EVP_DigestUpdate(&ctx, test->input, strlen(test->input))) {
  141. fprintf(stderr, "EVP_DigestUpdate failed\n");
  142. goto done;
  143. }
  144. }
  145. if (!EVP_DigestFinal_ex(&ctx, digest, &digest_len)) {
  146. fprintf(stderr, "EVP_DigestFinal_ex failed\n");
  147. goto done;
  148. }
  149. if (!compare_digest(test, digest, digest_len)) {
  150. goto done;
  151. }
  152. /* Test the input one character at a time. */
  153. if (!EVP_DigestInit_ex(&ctx, test->md_func(), NULL)) {
  154. fprintf(stderr, "EVP_DigestInit_ex failed\n");
  155. goto done;
  156. }
  157. if (!EVP_DigestUpdate(&ctx, NULL, 0)) {
  158. fprintf(stderr, "EVP_DigestUpdate failed\n");
  159. goto done;
  160. }
  161. for (i = 0; i < test->repeat; i++) {
  162. const char *p;
  163. for (p = test->input; *p; p++) {
  164. if (!EVP_DigestUpdate(&ctx, p, 1)) {
  165. fprintf(stderr, "EVP_DigestUpdate failed\n");
  166. goto done;
  167. }
  168. }
  169. }
  170. if (!EVP_DigestFinal_ex(&ctx, digest, &digest_len)) {
  171. fprintf(stderr, "EVP_DigestFinal_ex failed\n");
  172. goto done;
  173. }
  174. if (digest_len != EVP_MD_size(test->md_func())) {
  175. fprintf(stderr, "EVP_MD_size output incorrect\n");
  176. goto done;
  177. }
  178. if (!compare_digest(test, digest, digest_len)) {
  179. goto done;
  180. }
  181. /* Test the one-shot function. */
  182. if (test->one_shot_func && test->repeat == 1) {
  183. uint8_t *out = test->one_shot_func((const uint8_t *)test->input,
  184. strlen(test->input), digest);
  185. if (out != digest) {
  186. fprintf(stderr, "one_shot_func gave incorrect return\n");
  187. goto done;
  188. }
  189. if (!compare_digest(test, digest, EVP_MD_size(test->md_func()))) {
  190. goto done;
  191. }
  192. /* Test the deprecated static buffer variant, until it's removed. */
  193. out = test->one_shot_func((const uint8_t *)test->input, strlen(test->input),
  194. NULL);
  195. if (!compare_digest(test, out, EVP_MD_size(test->md_func()))) {
  196. goto done;
  197. }
  198. }
  199. ret = 1;
  200. done:
  201. EVP_MD_CTX_cleanup(&ctx);
  202. return ret;
  203. }
  204. int main(void) {
  205. size_t i;
  206. CRYPTO_library_init();
  207. ERR_load_crypto_strings();
  208. for (i = 0; i < sizeof(kTestVectors) / sizeof(kTestVectors[0]); i++) {
  209. if (!test_digest(&kTestVectors[i])) {
  210. fprintf(stderr, "Test %d failed\n", (int)i);
  211. return 1;
  212. }
  213. }
  214. printf("PASS\n");
  215. return 0;
  216. }