evp_test.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /* Written by Ben Laurie, 2001 */
  2. /*
  3. * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in
  14. * the documentation and/or other materials provided with the
  15. * distribution.
  16. *
  17. * 3. All advertising materials mentioning features or use of this
  18. * software must display the following acknowledgment:
  19. * "This product includes software developed by the OpenSSL Project
  20. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  21. *
  22. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  23. * endorse or promote products derived from this software without
  24. * prior written permission. For written permission, please contact
  25. * openssl-core@openssl.org.
  26. *
  27. * 5. Products derived from this software may not be called "OpenSSL"
  28. * nor may "OpenSSL" appear in their names without prior written
  29. * permission of the OpenSSL Project.
  30. *
  31. * 6. Redistributions of any form whatsoever must retain the following
  32. * acknowledgment:
  33. * "This product includes software developed by the OpenSSL Project
  34. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  35. *
  36. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  37. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  38. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  39. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  42. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  44. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  45. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  46. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  47. * OF THE POSSIBILITY OF SUCH DAMAGE.
  48. */
  49. #include <stdio.h>
  50. #include <string.h>
  51. #include "../e_os.h"
  52. #include <openssl/opensslconf.h>
  53. #include <openssl/evp.h>
  54. #ifndef OPENSSL_NO_ENGINE
  55. # include <openssl/engine.h>
  56. #endif
  57. #include <openssl/err.h>
  58. #include <openssl/conf.h>
  59. static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
  60. {
  61. int n = 0;
  62. fprintf(f, "%s", title);
  63. for (; n < l; ++n) {
  64. if ((n % 16) == 0)
  65. fprintf(f, "\n%04x", n);
  66. fprintf(f, " %02x", s[n]);
  67. }
  68. fprintf(f, "\n");
  69. }
  70. static int convert(unsigned char *s)
  71. {
  72. unsigned char *d;
  73. for (d = s; *s; s += 2, ++d) {
  74. unsigned int n;
  75. if (!s[1]) {
  76. fprintf(stderr, "Odd number of hex digits!");
  77. EXIT(4);
  78. }
  79. sscanf((char *)s, "%2x", &n);
  80. *d = (unsigned char)n;
  81. }
  82. return s - d;
  83. }
  84. static char *sstrsep(char **string, const char *delim)
  85. {
  86. char isdelim[256];
  87. char *token = *string;
  88. if (**string == 0)
  89. return NULL;
  90. memset(isdelim, 0, 256);
  91. isdelim[0] = 1;
  92. while (*delim) {
  93. isdelim[(unsigned char)(*delim)] = 1;
  94. delim++;
  95. }
  96. while (!isdelim[(unsigned char)(**string)]) {
  97. (*string)++;
  98. }
  99. if (**string) {
  100. **string = 0;
  101. (*string)++;
  102. }
  103. return token;
  104. }
  105. static unsigned char *ustrsep(char **p, const char *sep)
  106. {
  107. return (unsigned char *)sstrsep(p, sep);
  108. }
  109. static int test1_exit(int ec)
  110. {
  111. EXIT(ec);
  112. return (0); /* To keep some compilers quiet */
  113. }
  114. static void test1(const EVP_CIPHER *c, const unsigned char *key, int kn,
  115. const unsigned char *iv, int in,
  116. const unsigned char *plaintext, int pn,
  117. const unsigned char *ciphertext, int cn, int encdec)
  118. {
  119. EVP_CIPHER_CTX ctx;
  120. unsigned char out[4096];
  121. int outl, outl2;
  122. printf("Testing cipher %s%s\n", EVP_CIPHER_name(c),
  123. (encdec ==
  124. 1 ? "(encrypt)" : (encdec ==
  125. 0 ? "(decrypt)" : "(encrypt/decrypt)")));
  126. hexdump(stdout, "Key", key, kn);
  127. if (in)
  128. hexdump(stdout, "IV", iv, in);
  129. hexdump(stdout, "Plaintext", plaintext, pn);
  130. hexdump(stdout, "Ciphertext", ciphertext, cn);
  131. if (kn != c->key_len) {
  132. fprintf(stderr, "Key length doesn't match, got %d expected %d\n", kn,
  133. c->key_len);
  134. test1_exit(5);
  135. }
  136. EVP_CIPHER_CTX_init(&ctx);
  137. if (encdec != 0) {
  138. if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, iv)) {
  139. fprintf(stderr, "EncryptInit failed\n");
  140. ERR_print_errors_fp(stderr);
  141. test1_exit(10);
  142. }
  143. EVP_CIPHER_CTX_set_padding(&ctx, 0);
  144. if (!EVP_EncryptUpdate(&ctx, out, &outl, plaintext, pn)) {
  145. fprintf(stderr, "Encrypt failed\n");
  146. ERR_print_errors_fp(stderr);
  147. test1_exit(6);
  148. }
  149. if (!EVP_EncryptFinal_ex(&ctx, out + outl, &outl2)) {
  150. fprintf(stderr, "EncryptFinal failed\n");
  151. ERR_print_errors_fp(stderr);
  152. test1_exit(7);
  153. }
  154. if (outl + outl2 != cn) {
  155. fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n",
  156. outl + outl2, cn);
  157. test1_exit(8);
  158. }
  159. if (memcmp(out, ciphertext, cn)) {
  160. fprintf(stderr, "Ciphertext mismatch\n");
  161. hexdump(stderr, "Got", out, cn);
  162. hexdump(stderr, "Expected", ciphertext, cn);
  163. test1_exit(9);
  164. }
  165. }
  166. if (encdec <= 0) {
  167. if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, iv)) {
  168. fprintf(stderr, "DecryptInit failed\n");
  169. ERR_print_errors_fp(stderr);
  170. test1_exit(11);
  171. }
  172. EVP_CIPHER_CTX_set_padding(&ctx, 0);
  173. if (!EVP_DecryptUpdate(&ctx, out, &outl, ciphertext, cn)) {
  174. fprintf(stderr, "Decrypt failed\n");
  175. ERR_print_errors_fp(stderr);
  176. test1_exit(6);
  177. }
  178. if (!EVP_DecryptFinal_ex(&ctx, out + outl, &outl2)) {
  179. fprintf(stderr, "DecryptFinal failed\n");
  180. ERR_print_errors_fp(stderr);
  181. test1_exit(7);
  182. }
  183. if (outl + outl2 != pn) {
  184. fprintf(stderr, "Plaintext length mismatch got %d expected %d\n",
  185. outl + outl2, pn);
  186. test1_exit(8);
  187. }
  188. if (memcmp(out, plaintext, pn)) {
  189. fprintf(stderr, "Plaintext mismatch\n");
  190. hexdump(stderr, "Got", out, pn);
  191. hexdump(stderr, "Expected", plaintext, pn);
  192. test1_exit(9);
  193. }
  194. }
  195. EVP_CIPHER_CTX_cleanup(&ctx);
  196. printf("\n");
  197. }
  198. static int test_cipher(const char *cipher, const unsigned char *key, int kn,
  199. const unsigned char *iv, int in,
  200. const unsigned char *plaintext, int pn,
  201. const unsigned char *ciphertext, int cn, int encdec)
  202. {
  203. const EVP_CIPHER *c;
  204. c = EVP_get_cipherbyname(cipher);
  205. if (!c)
  206. return 0;
  207. test1(c, key, kn, iv, in, plaintext, pn, ciphertext, cn, encdec);
  208. return 1;
  209. }
  210. static int test_digest(const char *digest,
  211. const unsigned char *plaintext, int pn,
  212. const unsigned char *ciphertext, unsigned int cn)
  213. {
  214. const EVP_MD *d;
  215. EVP_MD_CTX ctx;
  216. unsigned char md[EVP_MAX_MD_SIZE];
  217. unsigned int mdn;
  218. d = EVP_get_digestbyname(digest);
  219. if (!d)
  220. return 0;
  221. printf("Testing digest %s\n", EVP_MD_name(d));
  222. hexdump(stdout, "Plaintext", plaintext, pn);
  223. hexdump(stdout, "Digest", ciphertext, cn);
  224. EVP_MD_CTX_init(&ctx);
  225. if (!EVP_DigestInit_ex(&ctx, d, NULL)) {
  226. fprintf(stderr, "DigestInit failed\n");
  227. ERR_print_errors_fp(stderr);
  228. EXIT(100);
  229. }
  230. if (!EVP_DigestUpdate(&ctx, plaintext, pn)) {
  231. fprintf(stderr, "DigestUpdate failed\n");
  232. ERR_print_errors_fp(stderr);
  233. EXIT(101);
  234. }
  235. if (!EVP_DigestFinal_ex(&ctx, md, &mdn)) {
  236. fprintf(stderr, "DigestFinal failed\n");
  237. ERR_print_errors_fp(stderr);
  238. EXIT(101);
  239. }
  240. EVP_MD_CTX_cleanup(&ctx);
  241. if (mdn != cn) {
  242. fprintf(stderr, "Digest length mismatch, got %d expected %d\n", mdn,
  243. cn);
  244. EXIT(102);
  245. }
  246. if (memcmp(md, ciphertext, cn)) {
  247. fprintf(stderr, "Digest mismatch\n");
  248. hexdump(stderr, "Got", md, cn);
  249. hexdump(stderr, "Expected", ciphertext, cn);
  250. EXIT(103);
  251. }
  252. printf("\n");
  253. EVP_MD_CTX_cleanup(&ctx);
  254. return 1;
  255. }
  256. int main(int argc, char **argv)
  257. {
  258. const char *szTestFile;
  259. FILE *f;
  260. if (argc != 2) {
  261. fprintf(stderr, "%s <test file>\n", argv[0]);
  262. EXIT(1);
  263. }
  264. CRYPTO_malloc_debug_init();
  265. CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
  266. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  267. szTestFile = argv[1];
  268. f = fopen(szTestFile, "r");
  269. if (!f) {
  270. perror(szTestFile);
  271. EXIT(2);
  272. }
  273. /* Load up the software EVP_CIPHER and EVP_MD definitions */
  274. OpenSSL_add_all_ciphers();
  275. OpenSSL_add_all_digests();
  276. #ifndef OPENSSL_NO_ENGINE
  277. /* Load all compiled-in ENGINEs */
  278. ENGINE_load_builtin_engines();
  279. #endif
  280. #if 0
  281. OPENSSL_config();
  282. #endif
  283. #ifndef OPENSSL_NO_ENGINE
  284. /*
  285. * Register all available ENGINE implementations of ciphers and digests.
  286. * This could perhaps be changed to "ENGINE_register_all_complete()"?
  287. */
  288. ENGINE_register_all_ciphers();
  289. ENGINE_register_all_digests();
  290. /*
  291. * If we add command-line options, this statement should be switchable.
  292. * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use
  293. * if they weren't already initialised.
  294. */
  295. /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */
  296. #endif
  297. for (;;) {
  298. char line[4096];
  299. char *p;
  300. char *cipher;
  301. unsigned char *iv, *key, *plaintext, *ciphertext;
  302. int encdec;
  303. int kn, in, pn, cn;
  304. if (!fgets((char *)line, sizeof line, f))
  305. break;
  306. if (line[0] == '#' || line[0] == '\n')
  307. continue;
  308. p = line;
  309. cipher = sstrsep(&p, ":");
  310. key = ustrsep(&p, ":");
  311. iv = ustrsep(&p, ":");
  312. plaintext = ustrsep(&p, ":");
  313. ciphertext = ustrsep(&p, ":");
  314. if (p[-1] == '\n') {
  315. p[-1] = '\0';
  316. encdec = -1;
  317. } else {
  318. encdec = atoi(sstrsep(&p, "\n"));
  319. }
  320. kn = convert(key);
  321. in = convert(iv);
  322. pn = convert(plaintext);
  323. cn = convert(ciphertext);
  324. if (!test_cipher
  325. (cipher, key, kn, iv, in, plaintext, pn, ciphertext, cn, encdec)
  326. && !test_digest(cipher, plaintext, pn, ciphertext, cn)) {
  327. #ifdef OPENSSL_NO_AES
  328. if (strstr(cipher, "AES") == cipher) {
  329. fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
  330. continue;
  331. }
  332. #endif
  333. #ifdef OPENSSL_NO_DES
  334. if (strstr(cipher, "DES") == cipher) {
  335. fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
  336. continue;
  337. }
  338. #endif
  339. #ifdef OPENSSL_NO_RC4
  340. if (strstr(cipher, "RC4") == cipher) {
  341. fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
  342. continue;
  343. }
  344. #endif
  345. #ifdef OPENSSL_NO_CAMELLIA
  346. if (strstr(cipher, "CAMELLIA") == cipher) {
  347. fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
  348. continue;
  349. }
  350. #endif
  351. #ifdef OPENSSL_NO_SEED
  352. if (strstr(cipher, "SEED") == cipher) {
  353. fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
  354. continue;
  355. }
  356. #endif
  357. fprintf(stderr, "Can't find %s\n", cipher);
  358. EXIT(3);
  359. }
  360. }
  361. fclose(f);
  362. #ifndef OPENSSL_NO_ENGINE
  363. ENGINE_cleanup();
  364. #endif
  365. EVP_cleanup();
  366. CRYPTO_cleanup_all_ex_data();
  367. ERR_remove_state(0);
  368. ERR_free_strings();
  369. CRYPTO_mem_leaks_fp(stderr);
  370. return 0;
  371. }