evp_test.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  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. {
  65. if((n%16) == 0)
  66. fprintf(f,"\n%04x",n);
  67. fprintf(f," %02x",s[n]);
  68. }
  69. fprintf(f,"\n");
  70. }
  71. static int convert(unsigned char *s)
  72. {
  73. unsigned char *d;
  74. for(d=s ; *s ; s+=2,++d)
  75. {
  76. unsigned int n;
  77. if(!s[1])
  78. {
  79. fprintf(stderr,"Odd number of hex digits!");
  80. EXIT(4);
  81. }
  82. sscanf((char *)s,"%2x",&n);
  83. *d=(unsigned char)n;
  84. }
  85. return s-d;
  86. }
  87. static char *sstrsep(char **string, const char *delim)
  88. {
  89. char isdelim[256];
  90. char *token = *string;
  91. if (**string == 0)
  92. return NULL;
  93. memset(isdelim, 0, 256);
  94. isdelim[0] = 1;
  95. while (*delim)
  96. {
  97. isdelim[(unsigned char)(*delim)] = 1;
  98. delim++;
  99. }
  100. while (!isdelim[(unsigned char)(**string)])
  101. {
  102. (*string)++;
  103. }
  104. if (**string)
  105. {
  106. **string = 0;
  107. (*string)++;
  108. }
  109. return token;
  110. }
  111. static unsigned char *ustrsep(char **p,const char *sep)
  112. { return (unsigned char *)sstrsep(p,sep); }
  113. static int test1_exit(int ec)
  114. {
  115. EXIT(ec);
  116. return(0); /* To keep some compilers quiet */
  117. }
  118. static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
  119. const unsigned char *iv,int in,
  120. const unsigned char *plaintext,int pn,
  121. const unsigned char *ciphertext,int cn,
  122. int encdec)
  123. {
  124. EVP_CIPHER_CTX ctx;
  125. unsigned char out[4096];
  126. int outl,outl2;
  127. printf("Testing cipher %s%s\n",EVP_CIPHER_name(c),
  128. (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)")));
  129. hexdump(stdout,"Key",key,kn);
  130. if(in)
  131. hexdump(stdout,"IV",iv,in);
  132. hexdump(stdout,"Plaintext",plaintext,pn);
  133. hexdump(stdout,"Ciphertext",ciphertext,cn);
  134. if(kn != c->key_len)
  135. {
  136. fprintf(stderr,"Key length doesn't match, got %d expected %d\n",kn,
  137. c->key_len);
  138. test1_exit(5);
  139. }
  140. EVP_CIPHER_CTX_init(&ctx);
  141. if (encdec != 0)
  142. {
  143. if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv))
  144. {
  145. fprintf(stderr,"EncryptInit failed\n");
  146. ERR_print_errors_fp(stderr);
  147. test1_exit(10);
  148. }
  149. EVP_CIPHER_CTX_set_padding(&ctx,0);
  150. if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn))
  151. {
  152. fprintf(stderr,"Encrypt failed\n");
  153. ERR_print_errors_fp(stderr);
  154. test1_exit(6);
  155. }
  156. if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2))
  157. {
  158. fprintf(stderr,"EncryptFinal failed\n");
  159. ERR_print_errors_fp(stderr);
  160. test1_exit(7);
  161. }
  162. if(outl+outl2 != cn)
  163. {
  164. fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n",
  165. outl+outl2,cn);
  166. test1_exit(8);
  167. }
  168. if(memcmp(out,ciphertext,cn))
  169. {
  170. fprintf(stderr,"Ciphertext mismatch\n");
  171. hexdump(stderr,"Got",out,cn);
  172. hexdump(stderr,"Expected",ciphertext,cn);
  173. test1_exit(9);
  174. }
  175. }
  176. if (encdec <= 0)
  177. {
  178. if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv))
  179. {
  180. fprintf(stderr,"DecryptInit failed\n");
  181. ERR_print_errors_fp(stderr);
  182. test1_exit(11);
  183. }
  184. EVP_CIPHER_CTX_set_padding(&ctx,0);
  185. if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn))
  186. {
  187. fprintf(stderr,"Decrypt failed\n");
  188. ERR_print_errors_fp(stderr);
  189. test1_exit(6);
  190. }
  191. if(!EVP_DecryptFinal_ex(&ctx,out+outl,&outl2))
  192. {
  193. fprintf(stderr,"DecryptFinal failed\n");
  194. ERR_print_errors_fp(stderr);
  195. test1_exit(7);
  196. }
  197. if(outl+outl2 != cn)
  198. {
  199. fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
  200. outl+outl2,cn);
  201. test1_exit(8);
  202. }
  203. if(memcmp(out,plaintext,cn))
  204. {
  205. fprintf(stderr,"Plaintext mismatch\n");
  206. hexdump(stderr,"Got",out,cn);
  207. hexdump(stderr,"Expected",plaintext,cn);
  208. test1_exit(9);
  209. }
  210. }
  211. EVP_CIPHER_CTX_cleanup(&ctx);
  212. printf("\n");
  213. }
  214. static int test_cipher(const char *cipher,const unsigned char *key,int kn,
  215. const unsigned char *iv,int in,
  216. const unsigned char *plaintext,int pn,
  217. const unsigned char *ciphertext,int cn,
  218. int encdec)
  219. {
  220. const EVP_CIPHER *c;
  221. c=EVP_get_cipherbyname(cipher);
  222. if(!c)
  223. return 0;
  224. test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec);
  225. return 1;
  226. }
  227. static int test_digest(const char *digest,
  228. const unsigned char *plaintext,int pn,
  229. const unsigned char *ciphertext, unsigned int cn)
  230. {
  231. const EVP_MD *d;
  232. EVP_MD_CTX ctx;
  233. unsigned char md[EVP_MAX_MD_SIZE];
  234. unsigned int mdn;
  235. d=EVP_get_digestbyname(digest);
  236. if(!d)
  237. return 0;
  238. printf("Testing digest %s\n",EVP_MD_name(d));
  239. hexdump(stdout,"Plaintext",plaintext,pn);
  240. hexdump(stdout,"Digest",ciphertext,cn);
  241. EVP_MD_CTX_init(&ctx);
  242. if(!EVP_DigestInit_ex(&ctx,d, NULL))
  243. {
  244. fprintf(stderr,"DigestInit failed\n");
  245. ERR_print_errors_fp(stderr);
  246. EXIT(100);
  247. }
  248. if(!EVP_DigestUpdate(&ctx,plaintext,pn))
  249. {
  250. fprintf(stderr,"DigestUpdate failed\n");
  251. ERR_print_errors_fp(stderr);
  252. EXIT(101);
  253. }
  254. if(!EVP_DigestFinal_ex(&ctx,md,&mdn))
  255. {
  256. fprintf(stderr,"DigestFinal failed\n");
  257. ERR_print_errors_fp(stderr);
  258. EXIT(101);
  259. }
  260. EVP_MD_CTX_cleanup(&ctx);
  261. if(mdn != cn)
  262. {
  263. fprintf(stderr,"Digest length mismatch, got %d expected %d\n",mdn,cn);
  264. EXIT(102);
  265. }
  266. if(memcmp(md,ciphertext,cn))
  267. {
  268. fprintf(stderr,"Digest mismatch\n");
  269. hexdump(stderr,"Got",md,cn);
  270. hexdump(stderr,"Expected",ciphertext,cn);
  271. EXIT(103);
  272. }
  273. printf("\n");
  274. EVP_MD_CTX_cleanup(&ctx);
  275. return 1;
  276. }
  277. int main(int argc,char **argv)
  278. {
  279. const char *szTestFile;
  280. FILE *f;
  281. if(argc != 2)
  282. {
  283. fprintf(stderr,"%s <test file>\n",argv[0]);
  284. EXIT(1);
  285. }
  286. CRYPTO_malloc_debug_init();
  287. CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
  288. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  289. szTestFile=argv[1];
  290. f=fopen(szTestFile,"r");
  291. if(!f)
  292. {
  293. perror(szTestFile);
  294. EXIT(2);
  295. }
  296. /* Load up the software EVP_CIPHER and EVP_MD definitions */
  297. OpenSSL_add_all_ciphers();
  298. OpenSSL_add_all_digests();
  299. #ifndef OPENSSL_NO_ENGINE
  300. /* Load all compiled-in ENGINEs */
  301. ENGINE_load_builtin_engines();
  302. #endif
  303. #if 0
  304. OPENSSL_config();
  305. #endif
  306. #ifndef OPENSSL_NO_ENGINE
  307. /* Register all available ENGINE implementations of ciphers and digests.
  308. * This could perhaps be changed to "ENGINE_register_all_complete()"? */
  309. ENGINE_register_all_ciphers();
  310. ENGINE_register_all_digests();
  311. /* If we add command-line options, this statement should be switchable.
  312. * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if
  313. * they weren't already initialised. */
  314. /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */
  315. #endif
  316. for( ; ; )
  317. {
  318. char line[4096];
  319. char *p;
  320. char *cipher;
  321. unsigned char *iv,*key,*plaintext,*ciphertext;
  322. int encdec;
  323. int kn,in,pn,cn;
  324. if(!fgets((char *)line,sizeof line,f))
  325. break;
  326. if(line[0] == '#' || line[0] == '\n')
  327. continue;
  328. p=line;
  329. cipher=sstrsep(&p,":");
  330. key=ustrsep(&p,":");
  331. iv=ustrsep(&p,":");
  332. plaintext=ustrsep(&p,":");
  333. ciphertext=ustrsep(&p,":");
  334. if (p[-1] == '\n') {
  335. p[-1] = '\0';
  336. encdec = -1;
  337. } else {
  338. encdec = atoi(sstrsep(&p,"\n"));
  339. }
  340. kn=convert(key);
  341. in=convert(iv);
  342. pn=convert(plaintext);
  343. cn=convert(ciphertext);
  344. if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec)
  345. && !test_digest(cipher,plaintext,pn,ciphertext,cn))
  346. {
  347. #ifdef OPENSSL_NO_AES
  348. if (strstr(cipher, "AES") == cipher)
  349. {
  350. fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
  351. continue;
  352. }
  353. #endif
  354. #ifdef OPENSSL_NO_DES
  355. if (strstr(cipher, "DES") == cipher)
  356. {
  357. fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
  358. continue;
  359. }
  360. #endif
  361. #ifdef OPENSSL_NO_RC4
  362. if (strstr(cipher, "RC4") == cipher)
  363. {
  364. fprintf(stdout, "Cipher disabled, skipping %s\n", cipher);
  365. continue;
  366. }
  367. #endif
  368. fprintf(stderr,"Can't find %s\n",cipher);
  369. EXIT(3);
  370. }
  371. }
  372. #ifndef OPENSSL_NO_ENGINE
  373. ENGINE_cleanup();
  374. #endif
  375. EVP_cleanup();
  376. CRYPTO_cleanup_all_ex_data();
  377. ERR_remove_state(0);
  378. ERR_free_strings();
  379. CRYPTO_mem_leaks_fp(stderr);
  380. return 0;
  381. }