]>
Commit | Line | Data |
---|---|---|
2d5d70b1 MC |
1 | /* engines/e_ossltest.c */ |
2 | /* | |
3 | * Written by Matt Caswell (matt@openssl.org) for the OpenSSL project. | |
4 | */ | |
5 | /* ==================================================================== | |
6 | * Copyright (c) 2015 The OpenSSL Project. All rights reserved. | |
7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * | |
12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in | |
17 | * the documentation and/or other materials provided with the | |
18 | * distribution. | |
19 | * | |
20 | * 3. All advertising materials mentioning features or use of this | |
21 | * software must display the following acknowledgment: | |
22 | * "This product includes software developed by the OpenSSL Project | |
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
24 | * | |
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
26 | * endorse or promote products derived from this software without | |
27 | * prior written permission. For written permission, please contact | |
28 | * licensing@OpenSSL.org. | |
29 | * | |
30 | * 5. Products derived from this software may not be called "OpenSSL" | |
31 | * nor may "OpenSSL" appear in their names without prior written | |
32 | * permission of the OpenSSL Project. | |
33 | * | |
34 | * 6. Redistributions of any form whatsoever must retain the following | |
35 | * acknowledgment: | |
36 | * "This product includes software developed by the OpenSSL Project | |
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
38 | * | |
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
51 | * ==================================================================== | |
52 | */ | |
53 | ||
54 | /* | |
55 | * This is the OSSLTEST engine. It provides deliberately crippled digest | |
56 | * implementations for test purposes. It is highly insecure and must NOT be | |
57 | * used for any purpose except testing | |
58 | */ | |
59 | ||
60 | #include <stdio.h> | |
61 | #include <string.h> | |
62 | ||
63 | #include <openssl/engine.h> | |
64 | #include <openssl/sha.h> | |
65 | #include <openssl/md5.h> | |
66 | #include <openssl/rsa.h> | |
67 | #include <openssl/evp.h> | |
68 | #include <openssl/modes.h> | |
69 | #include <openssl/aes.h> | |
70 | ||
71 | #define OSSLTEST_LIB_NAME "OSSLTEST" | |
72 | #include "e_ossltest_err.c" | |
73 | ||
74 | /* Engine Id and Name */ | |
75 | static const char *engine_ossltest_id = "ossltest"; | |
76 | static const char *engine_ossltest_name = "OpenSSL Test engine support"; | |
77 | ||
78 | ||
79 | /* Engine Lifetime functions */ | |
80 | static int ossltest_destroy(ENGINE *e); | |
81 | static int ossltest_init(ENGINE *e); | |
82 | static int ossltest_finish(ENGINE *e); | |
83 | void ENGINE_load_ossltest(void); | |
84 | ||
85 | ||
86 | /* Set up digests */ | |
87 | static int ossltest_digests(ENGINE *e, const EVP_MD **digest, | |
88 | const int **nids, int nid); | |
89 | ||
90 | static int ossltest_digest_nids[] = { | |
91 | NID_md5, NID_sha1, NID_sha256, NID_sha384, NID_sha512, 0 | |
92 | }; | |
93 | ||
94 | /* MD5 */ | |
95 | static int digest_md5_init(EVP_MD_CTX *ctx); | |
96 | static int digest_md5_update(EVP_MD_CTX *ctx, const void *data, | |
16a9542a | 97 | size_t count); |
2d5d70b1 MC |
98 | static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md); |
99 | ||
100 | static const EVP_MD digest_md5 = { | |
101 | NID_md5, | |
102 | NID_md5WithRSAEncryption, | |
103 | MD5_DIGEST_LENGTH, | |
104 | 0, | |
105 | digest_md5_init, | |
106 | digest_md5_update, | |
107 | digest_md5_final, | |
108 | NULL, | |
109 | NULL, | |
2d5d70b1 MC |
110 | MD5_CBLOCK, |
111 | sizeof(EVP_MD *) + sizeof(MD5_CTX), | |
112 | }; | |
113 | ||
114 | /* SHA1 */ | |
115 | static int digest_sha1_init(EVP_MD_CTX *ctx); | |
116 | static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data, | |
16a9542a | 117 | size_t count); |
2d5d70b1 MC |
118 | static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md); |
119 | ||
120 | static const EVP_MD digest_sha1 = { | |
121 | NID_sha1, | |
122 | NID_sha1WithRSAEncryption, | |
123 | SHA_DIGEST_LENGTH, | |
7f572e95 | 124 | EVP_MD_FLAG_DIGALGID_ABSENT, |
2d5d70b1 MC |
125 | digest_sha1_init, |
126 | digest_sha1_update, | |
127 | digest_sha1_final, | |
128 | NULL, | |
129 | NULL, | |
2d5d70b1 MC |
130 | SHA_CBLOCK, |
131 | sizeof(EVP_MD *) + sizeof(SHA_CTX), | |
132 | }; | |
133 | ||
134 | /* SHA256 */ | |
135 | static int digest_sha256_init(EVP_MD_CTX *ctx); | |
136 | static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data, | |
16a9542a | 137 | size_t count); |
2d5d70b1 MC |
138 | static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md); |
139 | ||
140 | static const EVP_MD digest_sha256 = { | |
141 | NID_sha256, | |
142 | NID_sha256WithRSAEncryption, | |
143 | SHA256_DIGEST_LENGTH, | |
7f572e95 | 144 | EVP_MD_FLAG_DIGALGID_ABSENT, |
2d5d70b1 MC |
145 | digest_sha256_init, |
146 | digest_sha256_update, | |
147 | digest_sha256_final, | |
148 | NULL, | |
149 | NULL, | |
2d5d70b1 MC |
150 | SHA256_CBLOCK, |
151 | sizeof(EVP_MD *) + sizeof(SHA256_CTX), | |
152 | }; | |
153 | ||
154 | /* SHA384/SHA512 */ | |
155 | static int digest_sha384_init(EVP_MD_CTX *ctx); | |
156 | static int digest_sha512_init(EVP_MD_CTX *ctx); | |
157 | static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data, | |
16a9542a | 158 | size_t count); |
2d5d70b1 MC |
159 | static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md); |
160 | static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md); | |
161 | ||
162 | static const EVP_MD digest_sha384 = { | |
163 | NID_sha384, | |
164 | NID_sha384WithRSAEncryption, | |
165 | SHA384_DIGEST_LENGTH, | |
7f572e95 | 166 | EVP_MD_FLAG_DIGALGID_ABSENT, |
2d5d70b1 MC |
167 | digest_sha384_init, |
168 | digest_sha512_update, | |
169 | digest_sha384_final, | |
170 | NULL, | |
171 | NULL, | |
2d5d70b1 MC |
172 | SHA512_CBLOCK, |
173 | sizeof(EVP_MD *) + sizeof(SHA512_CTX), | |
174 | }; | |
175 | ||
176 | static const EVP_MD digest_sha512 = { | |
177 | NID_sha512, | |
178 | NID_sha512WithRSAEncryption, | |
179 | SHA512_DIGEST_LENGTH, | |
7f572e95 | 180 | EVP_MD_FLAG_DIGALGID_ABSENT, |
2d5d70b1 MC |
181 | digest_sha512_init, |
182 | digest_sha512_update, | |
183 | digest_sha512_final, | |
184 | NULL, | |
185 | NULL, | |
2d5d70b1 MC |
186 | SHA512_CBLOCK, |
187 | sizeof(EVP_MD *) + sizeof(SHA512_CTX), | |
188 | }; | |
189 | ||
190 | /* Setup ciphers */ | |
191 | static int ossltest_ciphers(ENGINE *, const EVP_CIPHER **, | |
192 | const int **, int); | |
193 | ||
194 | static int ossltest_cipher_nids[] = { | |
195 | NID_aes_128_cbc, 0 | |
196 | }; | |
197 | ||
198 | /* AES128 */ | |
199 | ||
200 | int ossltest_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |
201 | const unsigned char *iv, int enc); | |
202 | int ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |
203 | const unsigned char *in, size_t inl); | |
204 | ||
2d5d70b1 MC |
205 | static const EVP_CIPHER ossltest_aes_128_cbc = { \ |
206 | NID_aes_128_cbc, | |
207 | 16, /* block size */ | |
208 | 16, /* key len */ | |
209 | 16, /* iv len */ | |
210 | EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CBC_MODE, | |
211 | ossltest_aes128_init_key, | |
212 | ossltest_aes128_cbc_cipher, | |
213 | NULL, | |
51a60817 | 214 | 0, /* We don't know the size of cipher_data at compile time */ |
2d5d70b1 MC |
215 | NULL,NULL,NULL,NULL |
216 | }; | |
217 | ||
218 | ||
219 | static int bind_ossltest(ENGINE *e) | |
220 | { | |
221 | /* Ensure the ossltest error handling is set up */ | |
222 | ERR_load_OSSLTEST_strings(); | |
223 | ||
224 | if (!ENGINE_set_id(e, engine_ossltest_id) | |
225 | || !ENGINE_set_name(e, engine_ossltest_name) | |
226 | || !ENGINE_set_digests(e, ossltest_digests) | |
227 | || !ENGINE_set_ciphers(e, ossltest_ciphers) | |
228 | || !ENGINE_set_destroy_function(e, ossltest_destroy) | |
229 | || !ENGINE_set_init_function(e, ossltest_init) | |
230 | || !ENGINE_set_finish_function(e, ossltest_finish)) { | |
231 | OSSLTESTerr(OSSLTEST_F_BIND_OSSLTEST, OSSLTEST_R_INIT_FAILED); | |
232 | return 0; | |
233 | } | |
234 | ||
235 | return 1; | |
236 | } | |
237 | ||
c0cbb4c1 | 238 | #ifndef OPENSSL_NO_DYNAMIC_ENGINE |
2d5d70b1 MC |
239 | static int bind_helper(ENGINE *e, const char *id) |
240 | { | |
241 | if (id && (strcmp(id, engine_ossltest_id) != 0)) | |
242 | return 0; | |
243 | if (!bind_ossltest(e)) | |
244 | return 0; | |
245 | return 1; | |
246 | } | |
247 | ||
248 | IMPLEMENT_DYNAMIC_CHECK_FN() | |
249 | IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) | |
c0cbb4c1 RL |
250 | #endif |
251 | ||
2d5d70b1 MC |
252 | static ENGINE *engine_ossltest(void) |
253 | { | |
254 | ENGINE *ret = ENGINE_new(); | |
55646005 | 255 | if (ret == NULL) |
2d5d70b1 MC |
256 | return NULL; |
257 | if (!bind_ossltest(ret)) { | |
258 | ENGINE_free(ret); | |
259 | return NULL; | |
260 | } | |
261 | return ret; | |
262 | } | |
263 | ||
264 | void ENGINE_load_ossltest(void) | |
265 | { | |
266 | /* Copied from eng_[openssl|dyn].c */ | |
267 | ENGINE *toadd = engine_ossltest(); | |
268 | if (!toadd) | |
269 | return; | |
270 | ENGINE_add(toadd); | |
271 | ENGINE_free(toadd); | |
272 | ERR_clear_error(); | |
273 | } | |
2d5d70b1 MC |
274 | |
275 | ||
276 | static int ossltest_init(ENGINE *e) | |
277 | { | |
278 | return 1; | |
279 | } | |
280 | ||
281 | ||
282 | static int ossltest_finish(ENGINE *e) | |
283 | { | |
284 | return 1; | |
285 | } | |
286 | ||
287 | ||
288 | static int ossltest_destroy(ENGINE *e) | |
289 | { | |
290 | ERR_unload_OSSLTEST_strings(); | |
291 | return 1; | |
292 | } | |
293 | ||
294 | static int ossltest_digests(ENGINE *e, const EVP_MD **digest, | |
295 | const int **nids, int nid) | |
296 | { | |
297 | int ok = 1; | |
298 | if (!digest) { | |
299 | /* We are returning a list of supported nids */ | |
300 | *nids = ossltest_digest_nids; | |
301 | return (sizeof(ossltest_digest_nids) - | |
302 | 1) / sizeof(ossltest_digest_nids[0]); | |
303 | } | |
304 | /* We are being asked for a specific digest */ | |
305 | switch (nid) { | |
306 | case NID_md5: | |
307 | *digest = &digest_md5; | |
308 | break; | |
309 | case NID_sha1: | |
310 | *digest = &digest_sha1; | |
311 | break; | |
312 | case NID_sha256: | |
313 | *digest = &digest_sha256; | |
314 | break; | |
315 | case NID_sha384: | |
316 | *digest = &digest_sha384; | |
317 | break; | |
318 | case NID_sha512: | |
319 | *digest = &digest_sha512; | |
320 | break; | |
321 | default: | |
322 | ok = 0; | |
323 | *digest = NULL; | |
324 | break; | |
325 | } | |
326 | return ok; | |
327 | } | |
328 | ||
329 | static int ossltest_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |
330 | const int **nids, int nid) | |
331 | { | |
332 | int ok = 1; | |
333 | if (!cipher) { | |
334 | /* We are returning a list of supported nids */ | |
335 | *nids = ossltest_cipher_nids; | |
336 | return (sizeof(ossltest_cipher_nids) - 1) | |
337 | / sizeof(ossltest_cipher_nids[0]); | |
338 | } | |
339 | /* We are being asked for a specific cipher */ | |
340 | switch (nid) { | |
341 | case NID_aes_128_cbc: | |
342 | *cipher = &ossltest_aes_128_cbc; | |
343 | break; | |
344 | default: | |
345 | ok = 0; | |
346 | *cipher = NULL; | |
347 | break; | |
348 | } | |
349 | return ok; | |
350 | } | |
351 | ||
352 | static void fill_known_data(unsigned char *md, unsigned int len) | |
353 | { | |
354 | unsigned int i; | |
355 | ||
356 | for (i=0; i<len; i++) { | |
357 | md[i] = (unsigned char)(i & 0xff); | |
358 | } | |
359 | } | |
360 | ||
361 | /* | |
362 | * MD5 implementation. We go through the motions of doing MD5 by deferring to | |
363 | * the standard implementation. Then we overwrite the result with a will defined | |
364 | * value, so that all "MD5" digests using the test engine always end up with | |
365 | * the same value. | |
366 | */ | |
367 | #undef data | |
6e59a892 | 368 | #define data(ctx) ((MD5_CTX *)EVP_MD_CTX_md_data(ctx)) |
2d5d70b1 MC |
369 | static int digest_md5_init(EVP_MD_CTX *ctx) |
370 | { | |
371 | return MD5_Init(data(ctx)); | |
372 | } | |
373 | ||
374 | static int digest_md5_update(EVP_MD_CTX *ctx, const void *data, | |
16a9542a | 375 | size_t count) |
2d5d70b1 MC |
376 | { |
377 | return MD5_Update(data(ctx), data, (size_t)count); | |
378 | } | |
379 | ||
380 | static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md) | |
381 | { | |
382 | int ret; | |
383 | ret = MD5_Final(md, data(ctx)); | |
384 | ||
385 | if (ret > 0) { | |
386 | fill_known_data(md, MD5_DIGEST_LENGTH); | |
387 | } | |
388 | return ret; | |
389 | } | |
390 | ||
391 | /* | |
392 | * SHA1 implementation. | |
393 | */ | |
394 | #undef data | |
6e59a892 | 395 | #define data(ctx) ((SHA_CTX *)EVP_MD_CTX_md_data(ctx)) |
2d5d70b1 MC |
396 | static int digest_sha1_init(EVP_MD_CTX *ctx) |
397 | { | |
398 | return SHA1_Init(data(ctx)); | |
399 | } | |
400 | ||
401 | static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data, | |
16a9542a | 402 | size_t count) |
2d5d70b1 MC |
403 | { |
404 | return SHA1_Update(data(ctx), data, (size_t)count); | |
405 | } | |
406 | ||
407 | static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) | |
408 | { | |
409 | int ret; | |
410 | ret = SHA1_Final(md, data(ctx)); | |
411 | ||
412 | if (ret > 0) { | |
413 | fill_known_data(md, SHA_DIGEST_LENGTH); | |
414 | } | |
415 | return ret; | |
416 | } | |
417 | ||
418 | /* | |
419 | * SHA256 implementation. | |
420 | */ | |
421 | #undef data | |
6e59a892 | 422 | #define data(ctx) ((SHA256_CTX *)EVP_MD_CTX_md_data(ctx)) |
2d5d70b1 MC |
423 | static int digest_sha256_init(EVP_MD_CTX *ctx) |
424 | { | |
425 | return SHA256_Init(data(ctx)); | |
426 | } | |
427 | ||
428 | static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data, | |
16a9542a | 429 | size_t count) |
2d5d70b1 MC |
430 | { |
431 | return SHA256_Update(data(ctx), data, (size_t)count); | |
432 | } | |
433 | ||
434 | static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md) | |
435 | { | |
436 | int ret; | |
437 | ret = SHA256_Final(md, data(ctx)); | |
438 | ||
439 | if (ret > 0) { | |
440 | fill_known_data(md, SHA256_DIGEST_LENGTH); | |
441 | } | |
442 | return ret; | |
443 | } | |
444 | ||
445 | /* | |
446 | * SHA384/512 implementation. | |
447 | */ | |
448 | #undef data | |
6e59a892 | 449 | #define data(ctx) ((SHA512_CTX *)EVP_MD_CTX_md_data(ctx)) |
2d5d70b1 MC |
450 | static int digest_sha384_init(EVP_MD_CTX *ctx) |
451 | { | |
452 | return SHA384_Init(data(ctx)); | |
453 | } | |
454 | ||
455 | static int digest_sha512_init(EVP_MD_CTX *ctx) | |
456 | { | |
457 | return SHA512_Init(data(ctx)); | |
458 | } | |
459 | ||
460 | static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data, | |
16a9542a | 461 | size_t count) |
2d5d70b1 MC |
462 | { |
463 | return SHA512_Update(data(ctx), data, (size_t)count); | |
464 | } | |
465 | ||
466 | static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md) | |
467 | { | |
468 | int ret; | |
469 | /* Actually uses SHA512_Final! */ | |
470 | ret = SHA512_Final(md, data(ctx)); | |
471 | ||
472 | if (ret > 0) { | |
473 | fill_known_data(md, SHA384_DIGEST_LENGTH); | |
474 | } | |
475 | return ret; | |
476 | } | |
477 | ||
478 | static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md) | |
479 | { | |
480 | int ret; | |
481 | ret = SHA512_Final(md, data(ctx)); | |
482 | ||
483 | if (ret > 0) { | |
484 | fill_known_data(md, SHA512_DIGEST_LENGTH); | |
485 | } | |
486 | return ret; | |
487 | } | |
488 | ||
489 | /* | |
490 | * AES128 Implementation | |
491 | */ | |
492 | ||
493 | int ossltest_aes128_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |
494 | const unsigned char *iv, int enc) | |
495 | { | |
51a60817 MC |
496 | if (ctx->cipher_data == NULL) { |
497 | /* | |
498 | * Normally cipher_data is allocated automatically for an engine but | |
499 | * we don't know the ctx_size as compile time so we have to do it at | |
500 | * run time | |
501 | */ | |
502 | ctx->cipher_data = OPENSSL_zalloc(EVP_aes_128_cbc()->ctx_size); | |
55646005 | 503 | if (ctx->cipher_data == NULL) { |
51a60817 MC |
504 | OSSLTESTerr(OSSLTEST_F_OSSLTEST_AES128_INIT_KEY, |
505 | ERR_R_MALLOC_FAILURE); | |
506 | return 0; | |
507 | } | |
508 | } | |
2d5d70b1 MC |
509 | return EVP_aes_128_cbc()->init(ctx, key, iv, enc); |
510 | } | |
511 | ||
512 | int ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |
513 | const unsigned char *in, size_t inl) | |
514 | { | |
515 | unsigned char *tmpbuf; | |
516 | int ret; | |
517 | ||
518 | tmpbuf = OPENSSL_malloc(inl); | |
519 | if (tmpbuf == NULL) | |
520 | return -1; | |
521 | ||
522 | /* Remember what we were asked to encrypt */ | |
523 | memcpy(tmpbuf, in, inl); | |
524 | ||
525 | /* Go through the motions of encrypting it */ | |
526 | ret = EVP_aes_128_cbc()->do_cipher(ctx, out, in, inl); | |
527 | ||
528 | /* Throw it all away and just use the plaintext as the output */ | |
529 | memcpy(out, tmpbuf, inl); | |
530 | OPENSSL_free(tmpbuf); | |
531 | ||
532 | return ret; | |
533 | } |