1 /* Written by Christian Heimes, 2013 */ 2 /* 3 * Copyright (c) 2013 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 50 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <string.h> 54 #include <errno.h> 55 56 #include <openssl/opensslconf.h> 57 #include <openssl/evp.h> 58 #ifndef OPENSSL_NO_ENGINE 59 #include <openssl/engine.h> 60 #endif 61 #include <openssl/err.h> 62 #include <openssl/conf.h> 63 64 typedef struct { 65 const char *pass; 66 int passlen; 67 const char *salt; 68 int saltlen; 69 int iter; 70 } testdata; 71 72 static const testdata test_cases[] = { 73 {"password", 8, "salt", 4, 1}, 74 {"password", 8, "salt", 4, 2}, 75 {"password", 8, "salt", 4, 4096}, 76 {"passwordPASSWORDpassword", 24, 77 "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096}, 78 {"pass\0word", 9, "sa\0lt", 5, 4096}, 79 {NULL}, 80 }; 81 82 static const char *sha1_results[] = { 83 "0c60c80f961f0e71f3a9b524af6012062fe037a6", 84 "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", 85 "4b007901b765489abead49d926f721d065a429c1", 86 "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", 87 "56fa6aa75548099dcc37d7f03425e0c3", 88 }; 89 90 static const char *sha256_results[] = { 91 "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b", 92 "ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43", 93 "c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a", 94 "348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c63551" 95 "8c7dac47e9", 96 "89b69d0516f829893c696226650a8687", 97 }; 98 99 static const char *sha512_results[] = { 100 "867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d47" 101 "0a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce", 102 "e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab" 103 "2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e", 104 "d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30" 105 "602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5", 106 "8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59" 107 "f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8", 108 "9d9e9c4cd21fe4be24d5b8244c759665", 109 }; 110 111 static void 112 hexdump(FILE *f, const char *title, const unsigned char *s, size_t len) 113 { 114 fprintf(f, "%s", title); 115 for (; len != 0; len--) 116 fprintf(f, " 0x%02x", *(s++)); 117 fprintf(f, "\n"); 118 } 119 120 static int 121 convert(unsigned char *dst, const unsigned char *src, size_t len) 122 { 123 unsigned int n; 124 125 for (; len != 0; src += 2, len--) { 126 if (sscanf((char *)src, "%2x", &n) != 1) 127 return EINVAL; 128 *dst++ = (unsigned char)n; 129 } 130 return 0; 131 } 132 133 static void 134 test_p5_pbkdf2(unsigned int n, const char *digestname, const testdata *test, 135 const char *hex) 136 { 137 const EVP_MD *digest; 138 unsigned char *out; 139 unsigned char *expected; 140 size_t keylen; 141 int r; 142 143 digest = EVP_get_digestbyname(digestname); 144 if (digest == NULL) { 145 fprintf(stderr, "unknown digest %s\n", digestname); 146 exit(5); 147 } 148 149 keylen = strlen(hex); 150 if ((keylen % 2) != 0) { 151 fprintf(stderr, "odd hex string %s, digest %u\n", digestname, n); 152 exit(5); 153 } 154 keylen /= 2; 155 expected = malloc(keylen); 156 out = malloc(keylen); 157 if (expected == NULL || out == NULL) { 158 fprintf(stderr, "malloc() failed\n"); 159 exit(5); 160 } 161 if (convert(expected, (const unsigned char *)hex, keylen) != 0) { 162 fprintf(stderr, "invalid hex string %s, digest %u\n", hex, n); 163 exit(5); 164 } 165 166 r = PKCS5_PBKDF2_HMAC(test->pass, test->passlen, 167 (const unsigned char *)test->salt, test->saltlen, 168 test->iter, digest, keylen, out); 169 170 if (r == 0) { 171 fprintf(stderr, "PKCS5_PBKDF2_HMAC(%s) failure test %u\n", 172 digestname, n); 173 exit(3); 174 } 175 if (memcmp(expected, out, keylen) != 0) { 176 fprintf(stderr, 177 "Wrong result for PKCS5_PBKDF2_HMAC(%s) test %u\n", 178 digestname, n); 179 hexdump(stderr, "expected: ", expected, keylen); 180 hexdump(stderr, "result: ", out, keylen); 181 exit(2); 182 } 183 free(expected); 184 free(out); 185 } 186 187 int 188 main(int argc,char **argv) 189 { 190 unsigned int n; 191 const testdata *test = test_cases; 192 193 OpenSSL_add_all_digests(); 194 #ifndef OPENSSL_NO_ENGINE 195 ENGINE_load_builtin_engines(); 196 ENGINE_register_all_digests(); 197 #endif 198 199 for (n = 0; test->pass != NULL; n++, test++) { 200 test_p5_pbkdf2(n, "sha1", test, sha1_results[n]); 201 test_p5_pbkdf2(n, "sha256", test, sha256_results[n]); 202 test_p5_pbkdf2(n, "sha512", test, sha512_results[n]); 203 } 204 205 #ifndef OPENSSL_NO_ENGINE 206 ENGINE_cleanup(); 207 #endif 208 EVP_cleanup(); 209 CRYPTO_cleanup_all_ex_data(); 210 ERR_remove_thread_state(NULL); 211 ERR_free_strings(); 212 return 0; 213 } 214