xref: /freebsd/crypto/openssl/engines/e_ossltest.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1e71b7053SJung-uk Kim /*
2*b077aed3SPierre Pronchery  * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim  *
4*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
8e71b7053SJung-uk Kim  */
9e71b7053SJung-uk Kim 
10e71b7053SJung-uk Kim /*
11e71b7053SJung-uk Kim  * This is the OSSLTEST engine. It provides deliberately crippled digest
12e71b7053SJung-uk Kim  * implementations for test purposes. It is highly insecure and must NOT be
13e71b7053SJung-uk Kim  * used for any purpose except testing
14e71b7053SJung-uk Kim  */
15e71b7053SJung-uk Kim 
16*b077aed3SPierre Pronchery /* We need to use some engine deprecated APIs */
17*b077aed3SPierre Pronchery #define OPENSSL_SUPPRESS_DEPRECATED
18*b077aed3SPierre Pronchery 
19*b077aed3SPierre Pronchery /*
20*b077aed3SPierre Pronchery  * SHA low level APIs are deprecated for public use, but still ok for
21*b077aed3SPierre Pronchery  * internal use.  Note, that due to symbols not being exported, only the
22*b077aed3SPierre Pronchery  * #defines and type definitions can be accessed, function calls are not
23*b077aed3SPierre Pronchery  * available.  The digest lengths, block sizes and sizeof(CTX) are used herein
24*b077aed3SPierre Pronchery  * for several different digests.
25*b077aed3SPierre Pronchery  */
26*b077aed3SPierre Pronchery #include "internal/deprecated.h"
27*b077aed3SPierre Pronchery 
28e71b7053SJung-uk Kim #include <stdio.h>
29e71b7053SJung-uk Kim #include <string.h>
30e71b7053SJung-uk Kim 
31e71b7053SJung-uk Kim #include <openssl/engine.h>
32e71b7053SJung-uk Kim #include <openssl/sha.h>
33e71b7053SJung-uk Kim #include <openssl/md5.h>
34e71b7053SJung-uk Kim #include <openssl/rsa.h>
35e71b7053SJung-uk Kim #include <openssl/evp.h>
36e71b7053SJung-uk Kim #include <openssl/modes.h>
37e71b7053SJung-uk Kim #include <openssl/aes.h>
38e71b7053SJung-uk Kim #include <openssl/rand.h>
39e71b7053SJung-uk Kim #include <openssl/crypto.h>
40*b077aed3SPierre Pronchery #include <openssl/pem.h>
41*b077aed3SPierre Pronchery #include <crypto/evp.h>
42e71b7053SJung-uk Kim 
43e71b7053SJung-uk Kim #include "e_ossltest_err.c"
44e71b7053SJung-uk Kim 
45e71b7053SJung-uk Kim /* Engine Id and Name */
46e71b7053SJung-uk Kim static const char *engine_ossltest_id = "ossltest";
47e71b7053SJung-uk Kim static const char *engine_ossltest_name = "OpenSSL Test engine support";
48e71b7053SJung-uk Kim 
49e71b7053SJung-uk Kim 
50e71b7053SJung-uk Kim /* Engine Lifetime functions */
51e71b7053SJung-uk Kim static int ossltest_destroy(ENGINE *e);
52e71b7053SJung-uk Kim static int ossltest_init(ENGINE *e);
53e71b7053SJung-uk Kim static int ossltest_finish(ENGINE *e);
54e71b7053SJung-uk Kim void ENGINE_load_ossltest(void);
55e71b7053SJung-uk Kim 
56e71b7053SJung-uk Kim 
57e71b7053SJung-uk Kim /* Set up digests */
58e71b7053SJung-uk Kim static int ossltest_digests(ENGINE *e, const EVP_MD **digest,
59e71b7053SJung-uk Kim                           const int **nids, int nid);
60e71b7053SJung-uk Kim static const RAND_METHOD *ossltest_rand_method(void);
61e71b7053SJung-uk Kim 
62e71b7053SJung-uk Kim /* MD5 */
63e71b7053SJung-uk Kim static int digest_md5_init(EVP_MD_CTX *ctx);
64e71b7053SJung-uk Kim static int digest_md5_update(EVP_MD_CTX *ctx, const void *data,
65e71b7053SJung-uk Kim                              size_t count);
66e71b7053SJung-uk Kim static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md);
67e71b7053SJung-uk Kim 
68e71b7053SJung-uk Kim static EVP_MD *_hidden_md5_md = NULL;
digest_md5(void)69e71b7053SJung-uk Kim static const EVP_MD *digest_md5(void)
70e71b7053SJung-uk Kim {
71e71b7053SJung-uk Kim     if (_hidden_md5_md == NULL) {
72e71b7053SJung-uk Kim         EVP_MD *md;
73e71b7053SJung-uk Kim 
74e71b7053SJung-uk Kim         if ((md = EVP_MD_meth_new(NID_md5, NID_md5WithRSAEncryption)) == NULL
75e71b7053SJung-uk Kim             || !EVP_MD_meth_set_result_size(md, MD5_DIGEST_LENGTH)
76e71b7053SJung-uk Kim             || !EVP_MD_meth_set_input_blocksize(md, MD5_CBLOCK)
77e71b7053SJung-uk Kim             || !EVP_MD_meth_set_app_datasize(md,
78e71b7053SJung-uk Kim                                              sizeof(EVP_MD *) + sizeof(MD5_CTX))
79e71b7053SJung-uk Kim             || !EVP_MD_meth_set_flags(md, 0)
80e71b7053SJung-uk Kim             || !EVP_MD_meth_set_init(md, digest_md5_init)
81e71b7053SJung-uk Kim             || !EVP_MD_meth_set_update(md, digest_md5_update)
82e71b7053SJung-uk Kim             || !EVP_MD_meth_set_final(md, digest_md5_final)) {
83e71b7053SJung-uk Kim             EVP_MD_meth_free(md);
84e71b7053SJung-uk Kim             md = NULL;
85e71b7053SJung-uk Kim         }
86e71b7053SJung-uk Kim         _hidden_md5_md = md;
87e71b7053SJung-uk Kim     }
88e71b7053SJung-uk Kim     return _hidden_md5_md;
89e71b7053SJung-uk Kim }
90e71b7053SJung-uk Kim 
91e71b7053SJung-uk Kim /* SHA1 */
92e71b7053SJung-uk Kim static int digest_sha1_init(EVP_MD_CTX *ctx);
93e71b7053SJung-uk Kim static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data,
94e71b7053SJung-uk Kim                               size_t count);
95e71b7053SJung-uk Kim static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);
96e71b7053SJung-uk Kim 
97e71b7053SJung-uk Kim static EVP_MD *_hidden_sha1_md = NULL;
digest_sha1(void)98e71b7053SJung-uk Kim static const EVP_MD *digest_sha1(void)
99e71b7053SJung-uk Kim {
100e71b7053SJung-uk Kim     if (_hidden_sha1_md == NULL) {
101e71b7053SJung-uk Kim         EVP_MD *md;
102e71b7053SJung-uk Kim 
103e71b7053SJung-uk Kim         if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL
104e71b7053SJung-uk Kim             || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
105e71b7053SJung-uk Kim             || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
106e71b7053SJung-uk Kim             || !EVP_MD_meth_set_app_datasize(md,
107e71b7053SJung-uk Kim                                              sizeof(EVP_MD *) + sizeof(SHA_CTX))
108e71b7053SJung-uk Kim             || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
109e71b7053SJung-uk Kim             || !EVP_MD_meth_set_init(md, digest_sha1_init)
110e71b7053SJung-uk Kim             || !EVP_MD_meth_set_update(md, digest_sha1_update)
111e71b7053SJung-uk Kim             || !EVP_MD_meth_set_final(md, digest_sha1_final)) {
112e71b7053SJung-uk Kim             EVP_MD_meth_free(md);
113e71b7053SJung-uk Kim             md = NULL;
114e71b7053SJung-uk Kim         }
115e71b7053SJung-uk Kim         _hidden_sha1_md = md;
116e71b7053SJung-uk Kim     }
117e71b7053SJung-uk Kim     return _hidden_sha1_md;
118e71b7053SJung-uk Kim }
119e71b7053SJung-uk Kim 
120e71b7053SJung-uk Kim /* SHA256 */
121e71b7053SJung-uk Kim static int digest_sha256_init(EVP_MD_CTX *ctx);
122e71b7053SJung-uk Kim static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data,
123e71b7053SJung-uk Kim                                 size_t count);
124e71b7053SJung-uk Kim static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md);
125e71b7053SJung-uk Kim 
126e71b7053SJung-uk Kim static EVP_MD *_hidden_sha256_md = NULL;
digest_sha256(void)127e71b7053SJung-uk Kim static const EVP_MD *digest_sha256(void)
128e71b7053SJung-uk Kim {
129e71b7053SJung-uk Kim     if (_hidden_sha256_md == NULL) {
130e71b7053SJung-uk Kim         EVP_MD *md;
131e71b7053SJung-uk Kim 
132e71b7053SJung-uk Kim         if ((md = EVP_MD_meth_new(NID_sha256, NID_sha256WithRSAEncryption)) == NULL
133e71b7053SJung-uk Kim             || !EVP_MD_meth_set_result_size(md, SHA256_DIGEST_LENGTH)
134e71b7053SJung-uk Kim             || !EVP_MD_meth_set_input_blocksize(md, SHA256_CBLOCK)
135e71b7053SJung-uk Kim             || !EVP_MD_meth_set_app_datasize(md,
136e71b7053SJung-uk Kim                                              sizeof(EVP_MD *) + sizeof(SHA256_CTX))
137e71b7053SJung-uk Kim             || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
138e71b7053SJung-uk Kim             || !EVP_MD_meth_set_init(md, digest_sha256_init)
139e71b7053SJung-uk Kim             || !EVP_MD_meth_set_update(md, digest_sha256_update)
140e71b7053SJung-uk Kim             || !EVP_MD_meth_set_final(md, digest_sha256_final)) {
141e71b7053SJung-uk Kim             EVP_MD_meth_free(md);
142e71b7053SJung-uk Kim             md = NULL;
143e71b7053SJung-uk Kim         }
144e71b7053SJung-uk Kim         _hidden_sha256_md = md;
145e71b7053SJung-uk Kim     }
146e71b7053SJung-uk Kim     return _hidden_sha256_md;
147e71b7053SJung-uk Kim }
148e71b7053SJung-uk Kim 
149e71b7053SJung-uk Kim /* SHA384/SHA512 */
150e71b7053SJung-uk Kim static int digest_sha384_init(EVP_MD_CTX *ctx);
151*b077aed3SPierre Pronchery static int digest_sha384_update(EVP_MD_CTX *ctx, const void *data,
152*b077aed3SPierre Pronchery                                 size_t count);
153*b077aed3SPierre Pronchery static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md);
154*b077aed3SPierre Pronchery 
155e71b7053SJung-uk Kim static int digest_sha512_init(EVP_MD_CTX *ctx);
156e71b7053SJung-uk Kim static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data,
157e71b7053SJung-uk Kim                                 size_t count);
158e71b7053SJung-uk Kim static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md);
159e71b7053SJung-uk Kim 
160e71b7053SJung-uk Kim static EVP_MD *_hidden_sha384_md = NULL;
digest_sha384(void)161e71b7053SJung-uk Kim static const EVP_MD *digest_sha384(void)
162e71b7053SJung-uk Kim {
163e71b7053SJung-uk Kim     if (_hidden_sha384_md == NULL) {
164e71b7053SJung-uk Kim         EVP_MD *md;
165e71b7053SJung-uk Kim 
166e71b7053SJung-uk Kim         if ((md = EVP_MD_meth_new(NID_sha384, NID_sha384WithRSAEncryption)) == NULL
167e71b7053SJung-uk Kim             || !EVP_MD_meth_set_result_size(md, SHA384_DIGEST_LENGTH)
168e71b7053SJung-uk Kim             || !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK)
169e71b7053SJung-uk Kim             || !EVP_MD_meth_set_app_datasize(md,
170e71b7053SJung-uk Kim                                              sizeof(EVP_MD *) + sizeof(SHA512_CTX))
171e71b7053SJung-uk Kim             || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
172e71b7053SJung-uk Kim             || !EVP_MD_meth_set_init(md, digest_sha384_init)
173*b077aed3SPierre Pronchery             || !EVP_MD_meth_set_update(md, digest_sha384_update)
174e71b7053SJung-uk Kim             || !EVP_MD_meth_set_final(md, digest_sha384_final)) {
175e71b7053SJung-uk Kim             EVP_MD_meth_free(md);
176e71b7053SJung-uk Kim             md = NULL;
177e71b7053SJung-uk Kim         }
178e71b7053SJung-uk Kim         _hidden_sha384_md = md;
179e71b7053SJung-uk Kim     }
180e71b7053SJung-uk Kim     return _hidden_sha384_md;
181e71b7053SJung-uk Kim }
182e71b7053SJung-uk Kim static EVP_MD *_hidden_sha512_md = NULL;
digest_sha512(void)183e71b7053SJung-uk Kim static const EVP_MD *digest_sha512(void)
184e71b7053SJung-uk Kim {
185e71b7053SJung-uk Kim     if (_hidden_sha512_md == NULL) {
186e71b7053SJung-uk Kim         EVP_MD *md;
187e71b7053SJung-uk Kim 
188e71b7053SJung-uk Kim         if ((md = EVP_MD_meth_new(NID_sha512, NID_sha512WithRSAEncryption)) == NULL
189e71b7053SJung-uk Kim             || !EVP_MD_meth_set_result_size(md, SHA512_DIGEST_LENGTH)
190e71b7053SJung-uk Kim             || !EVP_MD_meth_set_input_blocksize(md, SHA512_CBLOCK)
191e71b7053SJung-uk Kim             || !EVP_MD_meth_set_app_datasize(md,
192e71b7053SJung-uk Kim                                              sizeof(EVP_MD *) + sizeof(SHA512_CTX))
193e71b7053SJung-uk Kim             || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_DIGALGID_ABSENT)
194e71b7053SJung-uk Kim             || !EVP_MD_meth_set_init(md, digest_sha512_init)
195e71b7053SJung-uk Kim             || !EVP_MD_meth_set_update(md, digest_sha512_update)
196e71b7053SJung-uk Kim             || !EVP_MD_meth_set_final(md, digest_sha512_final)) {
197e71b7053SJung-uk Kim             EVP_MD_meth_free(md);
198e71b7053SJung-uk Kim             md = NULL;
199e71b7053SJung-uk Kim         }
200e71b7053SJung-uk Kim         _hidden_sha512_md = md;
201e71b7053SJung-uk Kim     }
202e71b7053SJung-uk Kim     return _hidden_sha512_md;
203e71b7053SJung-uk Kim }
destroy_digests(void)204e71b7053SJung-uk Kim static void destroy_digests(void)
205e71b7053SJung-uk Kim {
206e71b7053SJung-uk Kim     EVP_MD_meth_free(_hidden_md5_md);
207e71b7053SJung-uk Kim     _hidden_md5_md = NULL;
208e71b7053SJung-uk Kim     EVP_MD_meth_free(_hidden_sha1_md);
209e71b7053SJung-uk Kim     _hidden_sha1_md = NULL;
210e71b7053SJung-uk Kim     EVP_MD_meth_free(_hidden_sha256_md);
211e71b7053SJung-uk Kim     _hidden_sha256_md = NULL;
212e71b7053SJung-uk Kim     EVP_MD_meth_free(_hidden_sha384_md);
213e71b7053SJung-uk Kim     _hidden_sha384_md = NULL;
214e71b7053SJung-uk Kim     EVP_MD_meth_free(_hidden_sha512_md);
215e71b7053SJung-uk Kim     _hidden_sha512_md = NULL;
216e71b7053SJung-uk Kim }
ossltest_digest_nids(const int ** nids)217e71b7053SJung-uk Kim static int ossltest_digest_nids(const int **nids)
218e71b7053SJung-uk Kim {
219e71b7053SJung-uk Kim     static int digest_nids[6] = { 0, 0, 0, 0, 0, 0 };
220e71b7053SJung-uk Kim     static int pos = 0;
221e71b7053SJung-uk Kim     static int init = 0;
222e71b7053SJung-uk Kim 
223e71b7053SJung-uk Kim     if (!init) {
224e71b7053SJung-uk Kim         const EVP_MD *md;
225e71b7053SJung-uk Kim         if ((md = digest_md5()) != NULL)
226*b077aed3SPierre Pronchery             digest_nids[pos++] = EVP_MD_get_type(md);
227e71b7053SJung-uk Kim         if ((md = digest_sha1()) != NULL)
228*b077aed3SPierre Pronchery             digest_nids[pos++] = EVP_MD_get_type(md);
229e71b7053SJung-uk Kim         if ((md = digest_sha256()) != NULL)
230*b077aed3SPierre Pronchery             digest_nids[pos++] = EVP_MD_get_type(md);
231e71b7053SJung-uk Kim         if ((md = digest_sha384()) != NULL)
232*b077aed3SPierre Pronchery             digest_nids[pos++] = EVP_MD_get_type(md);
233e71b7053SJung-uk Kim         if ((md = digest_sha512()) != NULL)
234*b077aed3SPierre Pronchery             digest_nids[pos++] = EVP_MD_get_type(md);
235e71b7053SJung-uk Kim         digest_nids[pos] = 0;
236e71b7053SJung-uk Kim         init = 1;
237e71b7053SJung-uk Kim     }
238e71b7053SJung-uk Kim     *nids = digest_nids;
239e71b7053SJung-uk Kim     return pos;
240e71b7053SJung-uk Kim }
241e71b7053SJung-uk Kim 
242e71b7053SJung-uk Kim /* Setup ciphers */
243e71b7053SJung-uk Kim static int ossltest_ciphers(ENGINE *, const EVP_CIPHER **,
244e71b7053SJung-uk Kim                             const int **, int);
245e71b7053SJung-uk Kim 
246e71b7053SJung-uk Kim static int ossltest_cipher_nids[] = {
247*b077aed3SPierre Pronchery     NID_aes_128_cbc, NID_aes_128_gcm,
248*b077aed3SPierre Pronchery     NID_aes_128_cbc_hmac_sha1, 0
249e71b7053SJung-uk Kim };
250e71b7053SJung-uk Kim 
251e71b7053SJung-uk Kim /* AES128 */
252e71b7053SJung-uk Kim 
253*b077aed3SPierre Pronchery static int ossltest_aes128_init_key(EVP_CIPHER_CTX *ctx,
254*b077aed3SPierre Pronchery                                     const unsigned char *key,
255e71b7053SJung-uk Kim                                     const unsigned char *iv, int enc);
256*b077aed3SPierre Pronchery static int ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
257e71b7053SJung-uk Kim                                       const unsigned char *in, size_t inl);
258*b077aed3SPierre Pronchery static int ossltest_aes128_gcm_init_key(EVP_CIPHER_CTX *ctx,
259*b077aed3SPierre Pronchery                                         const unsigned char *key,
260e71b7053SJung-uk Kim                                         const unsigned char *iv, int enc);
261*b077aed3SPierre Pronchery static int ossltest_aes128_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
262e71b7053SJung-uk Kim                                       const unsigned char *in, size_t inl);
263e71b7053SJung-uk Kim static int ossltest_aes128_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
264e71b7053SJung-uk Kim                                     void *ptr);
265*b077aed3SPierre Pronchery static int ossltest_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
266*b077aed3SPierre Pronchery                                                   const unsigned char *key,
267*b077aed3SPierre Pronchery                                                   const unsigned char *iv,
268*b077aed3SPierre Pronchery                                                   int enc);
269*b077aed3SPierre Pronchery static int ossltest_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,
270*b077aed3SPierre Pronchery                                                 unsigned char *out,
271*b077aed3SPierre Pronchery                                                 const unsigned char *in,
272*b077aed3SPierre Pronchery                                                 size_t inl);
273*b077aed3SPierre Pronchery static int ossltest_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
274*b077aed3SPierre Pronchery                                               int arg, void *ptr);
275*b077aed3SPierre Pronchery 
276*b077aed3SPierre Pronchery typedef struct {
277*b077aed3SPierre Pronchery     size_t payload_length;      /* AAD length in decrypt case */
278*b077aed3SPierre Pronchery     unsigned int tls_ver;
279*b077aed3SPierre Pronchery } EVP_AES_HMAC_SHA1;
280e71b7053SJung-uk Kim 
281e71b7053SJung-uk Kim static EVP_CIPHER *_hidden_aes_128_cbc = NULL;
ossltest_aes_128_cbc(void)282e71b7053SJung-uk Kim static const EVP_CIPHER *ossltest_aes_128_cbc(void)
283e71b7053SJung-uk Kim {
284e71b7053SJung-uk Kim     if (_hidden_aes_128_cbc == NULL
285e71b7053SJung-uk Kim         && ((_hidden_aes_128_cbc = EVP_CIPHER_meth_new(NID_aes_128_cbc,
286e71b7053SJung-uk Kim                                                        16 /* block size */,
287e71b7053SJung-uk Kim                                                        16 /* key len */)) == NULL
288e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc,16)
289e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc,
290e71b7053SJung-uk Kim                                           EVP_CIPH_FLAG_DEFAULT_ASN1
291e71b7053SJung-uk Kim                                           | EVP_CIPH_CBC_MODE)
292e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc,
293e71b7053SJung-uk Kim                                          ossltest_aes128_init_key)
294e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc,
295e71b7053SJung-uk Kim                                               ossltest_aes128_cbc_cipher)
296e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc,
297e71b7053SJung-uk Kim                     EVP_CIPHER_impl_ctx_size(EVP_aes_128_cbc())))) {
298e71b7053SJung-uk Kim         EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
299e71b7053SJung-uk Kim         _hidden_aes_128_cbc = NULL;
300e71b7053SJung-uk Kim     }
301e71b7053SJung-uk Kim     return _hidden_aes_128_cbc;
302e71b7053SJung-uk Kim }
303*b077aed3SPierre Pronchery 
304e71b7053SJung-uk Kim static EVP_CIPHER *_hidden_aes_128_gcm = NULL;
305e71b7053SJung-uk Kim 
306e71b7053SJung-uk Kim #define AES_GCM_FLAGS   (EVP_CIPH_FLAG_DEFAULT_ASN1 \
307e71b7053SJung-uk Kim                 | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
308e71b7053SJung-uk Kim                 | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
309e71b7053SJung-uk Kim                 | EVP_CIPH_CUSTOM_COPY |EVP_CIPH_FLAG_AEAD_CIPHER \
310e71b7053SJung-uk Kim                 | EVP_CIPH_GCM_MODE)
311e71b7053SJung-uk Kim 
ossltest_aes_128_gcm(void)312e71b7053SJung-uk Kim static const EVP_CIPHER *ossltest_aes_128_gcm(void)
313e71b7053SJung-uk Kim {
314e71b7053SJung-uk Kim     if (_hidden_aes_128_gcm == NULL
315e71b7053SJung-uk Kim         && ((_hidden_aes_128_gcm = EVP_CIPHER_meth_new(NID_aes_128_gcm,
316e71b7053SJung-uk Kim                                                        1 /* block size */,
317e71b7053SJung-uk Kim                                                        16 /* key len */)) == NULL
318e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_gcm,12)
319e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_gcm, AES_GCM_FLAGS)
320e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_init(_hidden_aes_128_gcm,
321e71b7053SJung-uk Kim                                          ossltest_aes128_gcm_init_key)
322e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_gcm,
323e71b7053SJung-uk Kim                                               ossltest_aes128_gcm_cipher)
324e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_gcm,
325e71b7053SJung-uk Kim                                               ossltest_aes128_gcm_ctrl)
326e71b7053SJung-uk Kim             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_gcm,
327e71b7053SJung-uk Kim                     EVP_CIPHER_impl_ctx_size(EVP_aes_128_gcm())))) {
328e71b7053SJung-uk Kim         EVP_CIPHER_meth_free(_hidden_aes_128_gcm);
329e71b7053SJung-uk Kim         _hidden_aes_128_gcm = NULL;
330e71b7053SJung-uk Kim     }
331e71b7053SJung-uk Kim     return _hidden_aes_128_gcm;
332e71b7053SJung-uk Kim }
333e71b7053SJung-uk Kim 
334*b077aed3SPierre Pronchery static EVP_CIPHER *_hidden_aes_128_cbc_hmac_sha1 = NULL;
335*b077aed3SPierre Pronchery 
ossltest_aes_128_cbc_hmac_sha1(void)336*b077aed3SPierre Pronchery static const EVP_CIPHER *ossltest_aes_128_cbc_hmac_sha1(void)
337*b077aed3SPierre Pronchery {
338*b077aed3SPierre Pronchery     if (_hidden_aes_128_cbc_hmac_sha1 == NULL
339*b077aed3SPierre Pronchery         && ((_hidden_aes_128_cbc_hmac_sha1
340*b077aed3SPierre Pronchery              = EVP_CIPHER_meth_new(NID_aes_128_cbc_hmac_sha1,
341*b077aed3SPierre Pronchery                                    16 /* block size */,
342*b077aed3SPierre Pronchery                                    16 /* key len */)) == NULL
343*b077aed3SPierre Pronchery             || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_128_cbc_hmac_sha1,16)
344*b077aed3SPierre Pronchery             || !EVP_CIPHER_meth_set_flags(_hidden_aes_128_cbc_hmac_sha1,
345*b077aed3SPierre Pronchery                    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
346*b077aed3SPierre Pronchery                    EVP_CIPH_FLAG_AEAD_CIPHER)
347*b077aed3SPierre Pronchery             || !EVP_CIPHER_meth_set_init(_hidden_aes_128_cbc_hmac_sha1,
348*b077aed3SPierre Pronchery                    ossltest_aes128_cbc_hmac_sha1_init_key)
349*b077aed3SPierre Pronchery             || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_128_cbc_hmac_sha1,
350*b077aed3SPierre Pronchery                    ossltest_aes128_cbc_hmac_sha1_cipher)
351*b077aed3SPierre Pronchery             || !EVP_CIPHER_meth_set_ctrl(_hidden_aes_128_cbc_hmac_sha1,
352*b077aed3SPierre Pronchery                                          ossltest_aes128_cbc_hmac_sha1_ctrl)
353*b077aed3SPierre Pronchery             || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_aes_128_cbc_hmac_sha1,
354*b077aed3SPierre Pronchery                    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv)
355*b077aed3SPierre Pronchery             || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_aes_128_cbc_hmac_sha1,
356*b077aed3SPierre Pronchery                    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv)
357*b077aed3SPierre Pronchery             || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_128_cbc_hmac_sha1,
358*b077aed3SPierre Pronchery                    sizeof(EVP_AES_HMAC_SHA1)))) {
359*b077aed3SPierre Pronchery         EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
360*b077aed3SPierre Pronchery         _hidden_aes_128_cbc_hmac_sha1 = NULL;
361*b077aed3SPierre Pronchery     }
362*b077aed3SPierre Pronchery     return _hidden_aes_128_cbc_hmac_sha1;
363*b077aed3SPierre Pronchery }
364*b077aed3SPierre Pronchery 
destroy_ciphers(void)365e71b7053SJung-uk Kim static void destroy_ciphers(void)
366e71b7053SJung-uk Kim {
367e71b7053SJung-uk Kim     EVP_CIPHER_meth_free(_hidden_aes_128_cbc);
368e71b7053SJung-uk Kim     EVP_CIPHER_meth_free(_hidden_aes_128_gcm);
369*b077aed3SPierre Pronchery     EVP_CIPHER_meth_free(_hidden_aes_128_cbc_hmac_sha1);
370e71b7053SJung-uk Kim     _hidden_aes_128_cbc = NULL;
371*b077aed3SPierre Pronchery     _hidden_aes_128_gcm = NULL;
372*b077aed3SPierre Pronchery     _hidden_aes_128_cbc_hmac_sha1 = NULL;
373e71b7053SJung-uk Kim }
374e71b7053SJung-uk Kim 
375*b077aed3SPierre Pronchery /* Key loading */
load_key(ENGINE * eng,const char * key_id,int pub,UI_METHOD * ui_method,void * ui_data)376*b077aed3SPierre Pronchery static EVP_PKEY *load_key(ENGINE *eng, const char *key_id, int pub,
377*b077aed3SPierre Pronchery                           UI_METHOD *ui_method, void *ui_data)
378*b077aed3SPierre Pronchery {
379*b077aed3SPierre Pronchery     BIO *in;
380*b077aed3SPierre Pronchery     EVP_PKEY *key;
381*b077aed3SPierre Pronchery 
382*b077aed3SPierre Pronchery     if (OPENSSL_strncasecmp(key_id, "ot:", 3) != 0)
383*b077aed3SPierre Pronchery         return NULL;
384*b077aed3SPierre Pronchery     key_id += 3;
385*b077aed3SPierre Pronchery 
386*b077aed3SPierre Pronchery     fprintf(stderr, "[ossltest]Loading %s key %s\n",
387*b077aed3SPierre Pronchery             pub ? "Public" : "Private", key_id);
388*b077aed3SPierre Pronchery     in = BIO_new_file(key_id, "r");
389*b077aed3SPierre Pronchery     if (!in)
390*b077aed3SPierre Pronchery         return NULL;
391*b077aed3SPierre Pronchery     if (pub)
392*b077aed3SPierre Pronchery         key = PEM_read_bio_PUBKEY(in, NULL, 0, NULL);
393*b077aed3SPierre Pronchery     else
394*b077aed3SPierre Pronchery         key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
395*b077aed3SPierre Pronchery     BIO_free(in);
396*b077aed3SPierre Pronchery     return key;
397*b077aed3SPierre Pronchery }
398*b077aed3SPierre Pronchery 
ossltest_load_privkey(ENGINE * eng,const char * key_id,UI_METHOD * ui_method,void * ui_data)399*b077aed3SPierre Pronchery static EVP_PKEY *ossltest_load_privkey(ENGINE *eng, const char *key_id,
400*b077aed3SPierre Pronchery                                        UI_METHOD *ui_method, void *ui_data)
401*b077aed3SPierre Pronchery {
402*b077aed3SPierre Pronchery     return load_key(eng, key_id, 0, ui_method, ui_data);
403*b077aed3SPierre Pronchery }
404*b077aed3SPierre Pronchery 
ossltest_load_pubkey(ENGINE * eng,const char * key_id,UI_METHOD * ui_method,void * ui_data)405*b077aed3SPierre Pronchery static EVP_PKEY *ossltest_load_pubkey(ENGINE *eng, const char *key_id,
406*b077aed3SPierre Pronchery                                       UI_METHOD *ui_method, void *ui_data)
407*b077aed3SPierre Pronchery {
408*b077aed3SPierre Pronchery     return load_key(eng, key_id, 1, ui_method, ui_data);
409*b077aed3SPierre Pronchery }
410*b077aed3SPierre Pronchery 
411*b077aed3SPierre Pronchery 
bind_ossltest(ENGINE * e)412e71b7053SJung-uk Kim static int bind_ossltest(ENGINE *e)
413e71b7053SJung-uk Kim {
414e71b7053SJung-uk Kim     /* Ensure the ossltest error handling is set up */
415e71b7053SJung-uk Kim     ERR_load_OSSLTEST_strings();
416e71b7053SJung-uk Kim 
417e71b7053SJung-uk Kim     if (!ENGINE_set_id(e, engine_ossltest_id)
418e71b7053SJung-uk Kim         || !ENGINE_set_name(e, engine_ossltest_name)
419e71b7053SJung-uk Kim         || !ENGINE_set_digests(e, ossltest_digests)
420e71b7053SJung-uk Kim         || !ENGINE_set_ciphers(e, ossltest_ciphers)
421e71b7053SJung-uk Kim         || !ENGINE_set_RAND(e, ossltest_rand_method())
422e71b7053SJung-uk Kim         || !ENGINE_set_destroy_function(e, ossltest_destroy)
423*b077aed3SPierre Pronchery         || !ENGINE_set_load_privkey_function(e, ossltest_load_privkey)
424*b077aed3SPierre Pronchery         || !ENGINE_set_load_pubkey_function(e, ossltest_load_pubkey)
425e71b7053SJung-uk Kim         || !ENGINE_set_init_function(e, ossltest_init)
426e71b7053SJung-uk Kim         || !ENGINE_set_finish_function(e, ossltest_finish)) {
427e71b7053SJung-uk Kim         OSSLTESTerr(OSSLTEST_F_BIND_OSSLTEST, OSSLTEST_R_INIT_FAILED);
428e71b7053SJung-uk Kim         return 0;
429e71b7053SJung-uk Kim     }
430e71b7053SJung-uk Kim 
431e71b7053SJung-uk Kim     return 1;
432e71b7053SJung-uk Kim }
433e71b7053SJung-uk Kim 
434e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DYNAMIC_ENGINE
bind_helper(ENGINE * e,const char * id)435e71b7053SJung-uk Kim static int bind_helper(ENGINE *e, const char *id)
436e71b7053SJung-uk Kim {
437e71b7053SJung-uk Kim     if (id && (strcmp(id, engine_ossltest_id) != 0))
438e71b7053SJung-uk Kim         return 0;
439e71b7053SJung-uk Kim     if (!bind_ossltest(e))
440e71b7053SJung-uk Kim         return 0;
441e71b7053SJung-uk Kim     return 1;
442e71b7053SJung-uk Kim }
443e71b7053SJung-uk Kim 
444e71b7053SJung-uk Kim IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)445e71b7053SJung-uk Kim     IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
446e71b7053SJung-uk Kim #endif
447e71b7053SJung-uk Kim 
448e71b7053SJung-uk Kim static ENGINE *engine_ossltest(void)
449e71b7053SJung-uk Kim {
450e71b7053SJung-uk Kim     ENGINE *ret = ENGINE_new();
451e71b7053SJung-uk Kim     if (ret == NULL)
452e71b7053SJung-uk Kim         return NULL;
453e71b7053SJung-uk Kim     if (!bind_ossltest(ret)) {
454e71b7053SJung-uk Kim         ENGINE_free(ret);
455e71b7053SJung-uk Kim         return NULL;
456e71b7053SJung-uk Kim     }
457e71b7053SJung-uk Kim     return ret;
458e71b7053SJung-uk Kim }
459e71b7053SJung-uk Kim 
ENGINE_load_ossltest(void)460e71b7053SJung-uk Kim void ENGINE_load_ossltest(void)
461e71b7053SJung-uk Kim {
462e71b7053SJung-uk Kim     /* Copied from eng_[openssl|dyn].c */
463e71b7053SJung-uk Kim     ENGINE *toadd = engine_ossltest();
464e71b7053SJung-uk Kim     if (!toadd)
465e71b7053SJung-uk Kim         return;
466e71b7053SJung-uk Kim     ENGINE_add(toadd);
467e71b7053SJung-uk Kim     ENGINE_free(toadd);
468e71b7053SJung-uk Kim     ERR_clear_error();
469e71b7053SJung-uk Kim }
470e71b7053SJung-uk Kim 
471e71b7053SJung-uk Kim 
ossltest_init(ENGINE * e)472e71b7053SJung-uk Kim static int ossltest_init(ENGINE *e)
473e71b7053SJung-uk Kim {
474e71b7053SJung-uk Kim     return 1;
475e71b7053SJung-uk Kim }
476e71b7053SJung-uk Kim 
477e71b7053SJung-uk Kim 
ossltest_finish(ENGINE * e)478e71b7053SJung-uk Kim static int ossltest_finish(ENGINE *e)
479e71b7053SJung-uk Kim {
480e71b7053SJung-uk Kim     return 1;
481e71b7053SJung-uk Kim }
482e71b7053SJung-uk Kim 
483e71b7053SJung-uk Kim 
ossltest_destroy(ENGINE * e)484e71b7053SJung-uk Kim static int ossltest_destroy(ENGINE *e)
485e71b7053SJung-uk Kim {
486e71b7053SJung-uk Kim     destroy_digests();
487e71b7053SJung-uk Kim     destroy_ciphers();
488e71b7053SJung-uk Kim     ERR_unload_OSSLTEST_strings();
489e71b7053SJung-uk Kim     return 1;
490e71b7053SJung-uk Kim }
491e71b7053SJung-uk Kim 
ossltest_digests(ENGINE * e,const EVP_MD ** digest,const int ** nids,int nid)492e71b7053SJung-uk Kim static int ossltest_digests(ENGINE *e, const EVP_MD **digest,
493e71b7053SJung-uk Kim                           const int **nids, int nid)
494e71b7053SJung-uk Kim {
495e71b7053SJung-uk Kim     int ok = 1;
496e71b7053SJung-uk Kim     if (!digest) {
497e71b7053SJung-uk Kim         /* We are returning a list of supported nids */
498e71b7053SJung-uk Kim         return ossltest_digest_nids(nids);
499e71b7053SJung-uk Kim     }
500e71b7053SJung-uk Kim     /* We are being asked for a specific digest */
501e71b7053SJung-uk Kim     switch (nid) {
502e71b7053SJung-uk Kim     case NID_md5:
503e71b7053SJung-uk Kim         *digest = digest_md5();
504e71b7053SJung-uk Kim         break;
505e71b7053SJung-uk Kim     case NID_sha1:
506e71b7053SJung-uk Kim         *digest = digest_sha1();
507e71b7053SJung-uk Kim         break;
508e71b7053SJung-uk Kim     case NID_sha256:
509e71b7053SJung-uk Kim         *digest = digest_sha256();
510e71b7053SJung-uk Kim         break;
511e71b7053SJung-uk Kim     case NID_sha384:
512e71b7053SJung-uk Kim         *digest = digest_sha384();
513e71b7053SJung-uk Kim         break;
514e71b7053SJung-uk Kim     case NID_sha512:
515e71b7053SJung-uk Kim         *digest = digest_sha512();
516e71b7053SJung-uk Kim         break;
517e71b7053SJung-uk Kim     default:
518e71b7053SJung-uk Kim         ok = 0;
519e71b7053SJung-uk Kim         *digest = NULL;
520e71b7053SJung-uk Kim         break;
521e71b7053SJung-uk Kim     }
522e71b7053SJung-uk Kim     return ok;
523e71b7053SJung-uk Kim }
524e71b7053SJung-uk Kim 
ossltest_ciphers(ENGINE * e,const EVP_CIPHER ** cipher,const int ** nids,int nid)525e71b7053SJung-uk Kim static int ossltest_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
526e71b7053SJung-uk Kim                           const int **nids, int nid)
527e71b7053SJung-uk Kim {
528e71b7053SJung-uk Kim     int ok = 1;
529e71b7053SJung-uk Kim     if (!cipher) {
530e71b7053SJung-uk Kim         /* We are returning a list of supported nids */
531e71b7053SJung-uk Kim         *nids = ossltest_cipher_nids;
532e71b7053SJung-uk Kim         return (sizeof(ossltest_cipher_nids) - 1)
533e71b7053SJung-uk Kim                / sizeof(ossltest_cipher_nids[0]);
534e71b7053SJung-uk Kim     }
535e71b7053SJung-uk Kim     /* We are being asked for a specific cipher */
536e71b7053SJung-uk Kim     switch (nid) {
537e71b7053SJung-uk Kim     case NID_aes_128_cbc:
538e71b7053SJung-uk Kim         *cipher = ossltest_aes_128_cbc();
539e71b7053SJung-uk Kim         break;
540e71b7053SJung-uk Kim     case NID_aes_128_gcm:
541e71b7053SJung-uk Kim         *cipher = ossltest_aes_128_gcm();
542e71b7053SJung-uk Kim         break;
543*b077aed3SPierre Pronchery     case NID_aes_128_cbc_hmac_sha1:
544*b077aed3SPierre Pronchery         *cipher = ossltest_aes_128_cbc_hmac_sha1();
545*b077aed3SPierre Pronchery         break;
546e71b7053SJung-uk Kim     default:
547e71b7053SJung-uk Kim         ok = 0;
548e71b7053SJung-uk Kim         *cipher = NULL;
549e71b7053SJung-uk Kim         break;
550e71b7053SJung-uk Kim     }
551e71b7053SJung-uk Kim     return ok;
552e71b7053SJung-uk Kim }
553e71b7053SJung-uk Kim 
fill_known_data(unsigned char * md,unsigned int len)554e71b7053SJung-uk Kim static void fill_known_data(unsigned char *md, unsigned int len)
555e71b7053SJung-uk Kim {
556e71b7053SJung-uk Kim     unsigned int i;
557e71b7053SJung-uk Kim 
558e71b7053SJung-uk Kim     for (i=0; i<len; i++) {
559e71b7053SJung-uk Kim         md[i] = (unsigned char)(i & 0xff);
560e71b7053SJung-uk Kim     }
561e71b7053SJung-uk Kim }
562e71b7053SJung-uk Kim 
563e71b7053SJung-uk Kim /*
564e71b7053SJung-uk Kim  * MD5 implementation. We go through the motions of doing MD5 by deferring to
565e71b7053SJung-uk Kim  * the standard implementation. Then we overwrite the result with a will defined
566e71b7053SJung-uk Kim  * value, so that all "MD5" digests using the test engine always end up with
567e71b7053SJung-uk Kim  * the same value.
568e71b7053SJung-uk Kim  */
digest_md5_init(EVP_MD_CTX * ctx)569e71b7053SJung-uk Kim static int digest_md5_init(EVP_MD_CTX *ctx)
570e71b7053SJung-uk Kim {
571*b077aed3SPierre Pronchery    return EVP_MD_meth_get_init(EVP_md5())(ctx);
572e71b7053SJung-uk Kim }
573e71b7053SJung-uk Kim 
digest_md5_update(EVP_MD_CTX * ctx,const void * data,size_t count)574e71b7053SJung-uk Kim static int digest_md5_update(EVP_MD_CTX *ctx, const void *data,
575e71b7053SJung-uk Kim                              size_t count)
576e71b7053SJung-uk Kim {
577*b077aed3SPierre Pronchery     return EVP_MD_meth_get_update(EVP_md5())(ctx, data, count);
578e71b7053SJung-uk Kim }
579e71b7053SJung-uk Kim 
digest_md5_final(EVP_MD_CTX * ctx,unsigned char * md)580e71b7053SJung-uk Kim static int digest_md5_final(EVP_MD_CTX *ctx, unsigned char *md)
581e71b7053SJung-uk Kim {
582*b077aed3SPierre Pronchery     int ret = EVP_MD_meth_get_final(EVP_md5())(ctx, md);
583e71b7053SJung-uk Kim 
584e71b7053SJung-uk Kim     if (ret > 0) {
585e71b7053SJung-uk Kim         fill_known_data(md, MD5_DIGEST_LENGTH);
586e71b7053SJung-uk Kim     }
587e71b7053SJung-uk Kim     return ret;
588e71b7053SJung-uk Kim }
589e71b7053SJung-uk Kim 
590e71b7053SJung-uk Kim /*
591e71b7053SJung-uk Kim  * SHA1 implementation.
592e71b7053SJung-uk Kim  */
digest_sha1_init(EVP_MD_CTX * ctx)593e71b7053SJung-uk Kim static int digest_sha1_init(EVP_MD_CTX *ctx)
594e71b7053SJung-uk Kim {
595*b077aed3SPierre Pronchery     return EVP_MD_meth_get_init(EVP_sha1())(ctx);
596e71b7053SJung-uk Kim }
597e71b7053SJung-uk Kim 
digest_sha1_update(EVP_MD_CTX * ctx,const void * data,size_t count)598e71b7053SJung-uk Kim static int digest_sha1_update(EVP_MD_CTX *ctx, const void *data,
599e71b7053SJung-uk Kim                               size_t count)
600e71b7053SJung-uk Kim {
601*b077aed3SPierre Pronchery     return EVP_MD_meth_get_update(EVP_sha1())(ctx, data, count);
602e71b7053SJung-uk Kim }
603e71b7053SJung-uk Kim 
digest_sha1_final(EVP_MD_CTX * ctx,unsigned char * md)604e71b7053SJung-uk Kim static int digest_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
605e71b7053SJung-uk Kim {
606*b077aed3SPierre Pronchery     int ret = EVP_MD_meth_get_final(EVP_sha1())(ctx, md);
607e71b7053SJung-uk Kim 
608e71b7053SJung-uk Kim     if (ret > 0) {
609e71b7053SJung-uk Kim         fill_known_data(md, SHA_DIGEST_LENGTH);
610e71b7053SJung-uk Kim     }
611e71b7053SJung-uk Kim     return ret;
612e71b7053SJung-uk Kim }
613e71b7053SJung-uk Kim 
614e71b7053SJung-uk Kim /*
615e71b7053SJung-uk Kim  * SHA256 implementation.
616e71b7053SJung-uk Kim  */
digest_sha256_init(EVP_MD_CTX * ctx)617e71b7053SJung-uk Kim static int digest_sha256_init(EVP_MD_CTX *ctx)
618e71b7053SJung-uk Kim {
619*b077aed3SPierre Pronchery     return EVP_MD_meth_get_init(EVP_sha256())(ctx);
620e71b7053SJung-uk Kim }
621e71b7053SJung-uk Kim 
digest_sha256_update(EVP_MD_CTX * ctx,const void * data,size_t count)622e71b7053SJung-uk Kim static int digest_sha256_update(EVP_MD_CTX *ctx, const void *data,
623e71b7053SJung-uk Kim                                 size_t count)
624e71b7053SJung-uk Kim {
625*b077aed3SPierre Pronchery     return EVP_MD_meth_get_update(EVP_sha256())(ctx, data, count);
626e71b7053SJung-uk Kim }
627e71b7053SJung-uk Kim 
digest_sha256_final(EVP_MD_CTX * ctx,unsigned char * md)628e71b7053SJung-uk Kim static int digest_sha256_final(EVP_MD_CTX *ctx, unsigned char *md)
629e71b7053SJung-uk Kim {
630*b077aed3SPierre Pronchery     int ret = EVP_MD_meth_get_final(EVP_sha256())(ctx, md);
631e71b7053SJung-uk Kim 
632e71b7053SJung-uk Kim     if (ret > 0) {
633e71b7053SJung-uk Kim         fill_known_data(md, SHA256_DIGEST_LENGTH);
634e71b7053SJung-uk Kim     }
635e71b7053SJung-uk Kim     return ret;
636e71b7053SJung-uk Kim }
637e71b7053SJung-uk Kim 
638e71b7053SJung-uk Kim /*
639*b077aed3SPierre Pronchery  * SHA384 implementation.
640e71b7053SJung-uk Kim  */
digest_sha384_init(EVP_MD_CTX * ctx)641e71b7053SJung-uk Kim static int digest_sha384_init(EVP_MD_CTX *ctx)
642e71b7053SJung-uk Kim {
643*b077aed3SPierre Pronchery     return EVP_MD_meth_get_init(EVP_sha384())(ctx);
644e71b7053SJung-uk Kim }
645e71b7053SJung-uk Kim 
digest_sha384_update(EVP_MD_CTX * ctx,const void * data,size_t count)646*b077aed3SPierre Pronchery static int digest_sha384_update(EVP_MD_CTX *ctx, const void *data,
647e71b7053SJung-uk Kim                                 size_t count)
648e71b7053SJung-uk Kim {
649*b077aed3SPierre Pronchery     return EVP_MD_meth_get_update(EVP_sha384())(ctx, data, count);
650e71b7053SJung-uk Kim }
651e71b7053SJung-uk Kim 
digest_sha384_final(EVP_MD_CTX * ctx,unsigned char * md)652e71b7053SJung-uk Kim static int digest_sha384_final(EVP_MD_CTX *ctx, unsigned char *md)
653e71b7053SJung-uk Kim {
654*b077aed3SPierre Pronchery     int ret = EVP_MD_meth_get_final(EVP_sha384())(ctx, md);
655e71b7053SJung-uk Kim 
656e71b7053SJung-uk Kim     if (ret > 0) {
657e71b7053SJung-uk Kim         fill_known_data(md, SHA384_DIGEST_LENGTH);
658e71b7053SJung-uk Kim     }
659e71b7053SJung-uk Kim     return ret;
660e71b7053SJung-uk Kim }
661e71b7053SJung-uk Kim 
662*b077aed3SPierre Pronchery /*
663*b077aed3SPierre Pronchery  * SHA512 implementation.
664*b077aed3SPierre Pronchery  */
digest_sha512_init(EVP_MD_CTX * ctx)665*b077aed3SPierre Pronchery static int digest_sha512_init(EVP_MD_CTX *ctx)
666*b077aed3SPierre Pronchery {
667*b077aed3SPierre Pronchery     return EVP_MD_meth_get_init(EVP_sha512())(ctx);
668*b077aed3SPierre Pronchery }
669*b077aed3SPierre Pronchery 
digest_sha512_update(EVP_MD_CTX * ctx,const void * data,size_t count)670*b077aed3SPierre Pronchery static int digest_sha512_update(EVP_MD_CTX *ctx, const void *data,
671*b077aed3SPierre Pronchery                                 size_t count)
672*b077aed3SPierre Pronchery {
673*b077aed3SPierre Pronchery     return EVP_MD_meth_get_update(EVP_sha512())(ctx, data, count);
674*b077aed3SPierre Pronchery }
675*b077aed3SPierre Pronchery 
digest_sha512_final(EVP_MD_CTX * ctx,unsigned char * md)676e71b7053SJung-uk Kim static int digest_sha512_final(EVP_MD_CTX *ctx, unsigned char *md)
677e71b7053SJung-uk Kim {
678*b077aed3SPierre Pronchery     int ret = EVP_MD_meth_get_final(EVP_sha512())(ctx, md);
679e71b7053SJung-uk Kim 
680e71b7053SJung-uk Kim     if (ret > 0) {
681e71b7053SJung-uk Kim         fill_known_data(md, SHA512_DIGEST_LENGTH);
682e71b7053SJung-uk Kim     }
683e71b7053SJung-uk Kim     return ret;
684e71b7053SJung-uk Kim }
685e71b7053SJung-uk Kim 
686e71b7053SJung-uk Kim /*
687e71b7053SJung-uk Kim  * AES128 Implementation
688e71b7053SJung-uk Kim  */
689e71b7053SJung-uk Kim 
ossltest_aes128_init_key(EVP_CIPHER_CTX * ctx,const unsigned char * key,const unsigned char * iv,int enc)690*b077aed3SPierre Pronchery static int ossltest_aes128_init_key(EVP_CIPHER_CTX *ctx,
691*b077aed3SPierre Pronchery                                     const unsigned char *key,
692e71b7053SJung-uk Kim                                     const unsigned char *iv, int enc)
693e71b7053SJung-uk Kim {
694e71b7053SJung-uk Kim     return EVP_CIPHER_meth_get_init(EVP_aes_128_cbc()) (ctx, key, iv, enc);
695e71b7053SJung-uk Kim }
696e71b7053SJung-uk Kim 
ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)697*b077aed3SPierre Pronchery static int ossltest_aes128_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
698e71b7053SJung-uk Kim                                       const unsigned char *in, size_t inl)
699e71b7053SJung-uk Kim {
700e71b7053SJung-uk Kim     unsigned char *tmpbuf;
701e71b7053SJung-uk Kim     int ret;
702e71b7053SJung-uk Kim 
703e71b7053SJung-uk Kim     tmpbuf = OPENSSL_malloc(inl);
704e71b7053SJung-uk Kim 
705e71b7053SJung-uk Kim     /* OPENSSL_malloc will return NULL if inl == 0 */
706e71b7053SJung-uk Kim     if (tmpbuf == NULL && inl > 0)
707e71b7053SJung-uk Kim         return -1;
708e71b7053SJung-uk Kim 
709e71b7053SJung-uk Kim     /* Remember what we were asked to encrypt */
710e71b7053SJung-uk Kim     if (tmpbuf != NULL)
711e71b7053SJung-uk Kim         memcpy(tmpbuf, in, inl);
712e71b7053SJung-uk Kim 
713e71b7053SJung-uk Kim     /* Go through the motions of encrypting it */
714e71b7053SJung-uk Kim     ret = EVP_CIPHER_meth_get_do_cipher(EVP_aes_128_cbc())(ctx, out, in, inl);
715e71b7053SJung-uk Kim 
716e71b7053SJung-uk Kim     /* Throw it all away and just use the plaintext as the output */
717e71b7053SJung-uk Kim     if (tmpbuf != NULL)
718e71b7053SJung-uk Kim         memcpy(out, tmpbuf, inl);
719e71b7053SJung-uk Kim     OPENSSL_free(tmpbuf);
720e71b7053SJung-uk Kim 
721e71b7053SJung-uk Kim     return ret;
722e71b7053SJung-uk Kim }
723e71b7053SJung-uk Kim 
ossltest_aes128_gcm_init_key(EVP_CIPHER_CTX * ctx,const unsigned char * key,const unsigned char * iv,int enc)724*b077aed3SPierre Pronchery static int ossltest_aes128_gcm_init_key(EVP_CIPHER_CTX *ctx,
725*b077aed3SPierre Pronchery                                         const unsigned char *key,
726e71b7053SJung-uk Kim                                         const unsigned char *iv, int enc)
727e71b7053SJung-uk Kim {
728e71b7053SJung-uk Kim     return EVP_CIPHER_meth_get_init(EVP_aes_128_gcm()) (ctx, key, iv, enc);
729e71b7053SJung-uk Kim }
730e71b7053SJung-uk Kim 
ossltest_aes128_gcm_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)731*b077aed3SPierre Pronchery static int ossltest_aes128_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
732e71b7053SJung-uk Kim                                       const unsigned char *in, size_t inl)
733e71b7053SJung-uk Kim {
734e71b7053SJung-uk Kim     unsigned char *tmpbuf = OPENSSL_malloc(inl);
735e71b7053SJung-uk Kim 
736e71b7053SJung-uk Kim     /* OPENSSL_malloc will return NULL if inl == 0 */
737e71b7053SJung-uk Kim     if (tmpbuf == NULL && inl > 0)
738e71b7053SJung-uk Kim         return -1;
739e71b7053SJung-uk Kim 
740e71b7053SJung-uk Kim     /* Remember what we were asked to encrypt */
741e71b7053SJung-uk Kim     if (tmpbuf != NULL)
742e71b7053SJung-uk Kim         memcpy(tmpbuf, in, inl);
743e71b7053SJung-uk Kim 
744e71b7053SJung-uk Kim     /* Go through the motions of encrypting it */
745e71b7053SJung-uk Kim     EVP_CIPHER_meth_get_do_cipher(EVP_aes_128_gcm())(ctx, out, in, inl);
746e71b7053SJung-uk Kim 
747e71b7053SJung-uk Kim     /* Throw it all away and just use the plaintext as the output */
748e71b7053SJung-uk Kim     if (tmpbuf != NULL && out != NULL)
749e71b7053SJung-uk Kim         memcpy(out, tmpbuf, inl);
750e71b7053SJung-uk Kim     OPENSSL_free(tmpbuf);
751e71b7053SJung-uk Kim 
752e71b7053SJung-uk Kim     return inl;
753e71b7053SJung-uk Kim }
754e71b7053SJung-uk Kim 
ossltest_aes128_gcm_ctrl(EVP_CIPHER_CTX * ctx,int type,int arg,void * ptr)755e71b7053SJung-uk Kim static int ossltest_aes128_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
756e71b7053SJung-uk Kim                                     void *ptr)
757e71b7053SJung-uk Kim {
758e71b7053SJung-uk Kim     /* Pass the ctrl down */
759e71b7053SJung-uk Kim     int ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_gcm())(ctx, type, arg, ptr);
760e71b7053SJung-uk Kim 
761e71b7053SJung-uk Kim     if (ret <= 0)
762e71b7053SJung-uk Kim         return ret;
763e71b7053SJung-uk Kim 
764e71b7053SJung-uk Kim     switch(type) {
765e71b7053SJung-uk Kim     case EVP_CTRL_AEAD_GET_TAG:
766e71b7053SJung-uk Kim         /* Always give the same tag */
767e71b7053SJung-uk Kim         memset(ptr, 0, EVP_GCM_TLS_TAG_LEN);
768e71b7053SJung-uk Kim         break;
769e71b7053SJung-uk Kim 
770e71b7053SJung-uk Kim     default:
771e71b7053SJung-uk Kim         break;
772e71b7053SJung-uk Kim     }
773e71b7053SJung-uk Kim 
774e71b7053SJung-uk Kim     return 1;
775e71b7053SJung-uk Kim }
776e71b7053SJung-uk Kim 
777*b077aed3SPierre Pronchery #define NO_PAYLOAD_LENGTH       ((size_t)-1)
778*b077aed3SPierre Pronchery # define data(ctx) ((EVP_AES_HMAC_SHA1 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
779*b077aed3SPierre Pronchery 
ossltest_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX * ctx,const unsigned char * inkey,const unsigned char * iv,int enc)780*b077aed3SPierre Pronchery static int ossltest_aes128_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
781*b077aed3SPierre Pronchery                                                   const unsigned char *inkey,
782*b077aed3SPierre Pronchery                                                   const unsigned char *iv,
783*b077aed3SPierre Pronchery                                                   int enc)
784*b077aed3SPierre Pronchery {
785*b077aed3SPierre Pronchery     EVP_AES_HMAC_SHA1 *key = data(ctx);
786*b077aed3SPierre Pronchery     key->payload_length = NO_PAYLOAD_LENGTH;
787*b077aed3SPierre Pronchery     return 1;
788*b077aed3SPierre Pronchery }
789*b077aed3SPierre Pronchery 
ossltest_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t len)790*b077aed3SPierre Pronchery static int ossltest_aes128_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx,
791*b077aed3SPierre Pronchery                                                 unsigned char *out,
792*b077aed3SPierre Pronchery                                                 const unsigned char *in,
793*b077aed3SPierre Pronchery                                                 size_t len)
794*b077aed3SPierre Pronchery {
795*b077aed3SPierre Pronchery     EVP_AES_HMAC_SHA1 *key = data(ctx);
796*b077aed3SPierre Pronchery     unsigned int l;
797*b077aed3SPierre Pronchery     size_t plen = key->payload_length;
798*b077aed3SPierre Pronchery 
799*b077aed3SPierre Pronchery     key->payload_length = NO_PAYLOAD_LENGTH;
800*b077aed3SPierre Pronchery 
801*b077aed3SPierre Pronchery     if (len % AES_BLOCK_SIZE)
802*b077aed3SPierre Pronchery         return 0;
803*b077aed3SPierre Pronchery 
804*b077aed3SPierre Pronchery     if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
805*b077aed3SPierre Pronchery         if (plen == NO_PAYLOAD_LENGTH)
806*b077aed3SPierre Pronchery             plen = len;
807*b077aed3SPierre Pronchery         else if (len !=
808*b077aed3SPierre Pronchery                  ((plen + SHA_DIGEST_LENGTH +
809*b077aed3SPierre Pronchery                    AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))
810*b077aed3SPierre Pronchery             return 0;
811*b077aed3SPierre Pronchery 
812*b077aed3SPierre Pronchery         memmove(out, in, plen);
813*b077aed3SPierre Pronchery 
814*b077aed3SPierre Pronchery         if (plen != len) {      /* "TLS" mode of operation */
815*b077aed3SPierre Pronchery             /* calculate HMAC and append it to payload */
816*b077aed3SPierre Pronchery             fill_known_data(out + plen, SHA_DIGEST_LENGTH);
817*b077aed3SPierre Pronchery 
818*b077aed3SPierre Pronchery             /* pad the payload|hmac */
819*b077aed3SPierre Pronchery             plen += SHA_DIGEST_LENGTH;
820*b077aed3SPierre Pronchery             for (l = len - plen - 1; plen < len; plen++)
821*b077aed3SPierre Pronchery                 out[plen] = l;
822*b077aed3SPierre Pronchery         }
823*b077aed3SPierre Pronchery     } else {
824*b077aed3SPierre Pronchery         /* decrypt HMAC|padding at once */
825*b077aed3SPierre Pronchery         memmove(out, in, len);
826*b077aed3SPierre Pronchery 
827*b077aed3SPierre Pronchery         if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
828*b077aed3SPierre Pronchery             unsigned int maxpad, pad;
829*b077aed3SPierre Pronchery 
830*b077aed3SPierre Pronchery             if (key->tls_ver >= TLS1_1_VERSION) {
831*b077aed3SPierre Pronchery                 if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1))
832*b077aed3SPierre Pronchery                     return 0;
833*b077aed3SPierre Pronchery 
834*b077aed3SPierre Pronchery                 /* omit explicit iv */
835*b077aed3SPierre Pronchery                 in += AES_BLOCK_SIZE;
836*b077aed3SPierre Pronchery                 out += AES_BLOCK_SIZE;
837*b077aed3SPierre Pronchery                 len -= AES_BLOCK_SIZE;
838*b077aed3SPierre Pronchery             } else if (len < (SHA_DIGEST_LENGTH + 1))
839*b077aed3SPierre Pronchery                 return 0;
840*b077aed3SPierre Pronchery 
841*b077aed3SPierre Pronchery             /* figure out payload length */
842*b077aed3SPierre Pronchery             pad = out[len - 1];
843*b077aed3SPierre Pronchery             maxpad = len - (SHA_DIGEST_LENGTH + 1);
844*b077aed3SPierre Pronchery             if (pad > maxpad)
845*b077aed3SPierre Pronchery                 return 0;
846*b077aed3SPierre Pronchery             for (plen = len - pad - 1; plen < len; plen++)
847*b077aed3SPierre Pronchery                 if (out[plen] != pad)
848*b077aed3SPierre Pronchery                     return 0;
849*b077aed3SPierre Pronchery         }
850*b077aed3SPierre Pronchery     }
851*b077aed3SPierre Pronchery 
852*b077aed3SPierre Pronchery     return 1;
853*b077aed3SPierre Pronchery }
854*b077aed3SPierre Pronchery 
ossltest_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX * ctx,int type,int arg,void * ptr)855*b077aed3SPierre Pronchery static int ossltest_aes128_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
856*b077aed3SPierre Pronchery                                               int arg, void *ptr)
857*b077aed3SPierre Pronchery {
858*b077aed3SPierre Pronchery     EVP_AES_HMAC_SHA1 *key = data(ctx);
859*b077aed3SPierre Pronchery 
860*b077aed3SPierre Pronchery     switch (type) {
861*b077aed3SPierre Pronchery     case EVP_CTRL_AEAD_SET_MAC_KEY:
862*b077aed3SPierre Pronchery         return 1;
863*b077aed3SPierre Pronchery 
864*b077aed3SPierre Pronchery     case EVP_CTRL_AEAD_TLS1_AAD:
865*b077aed3SPierre Pronchery         {
866*b077aed3SPierre Pronchery             unsigned char *p = ptr;
867*b077aed3SPierre Pronchery             unsigned int len;
868*b077aed3SPierre Pronchery 
869*b077aed3SPierre Pronchery             if (arg != EVP_AEAD_TLS1_AAD_LEN)
870*b077aed3SPierre Pronchery                 return -1;
871*b077aed3SPierre Pronchery 
872*b077aed3SPierre Pronchery             len = p[arg - 2] << 8 | p[arg - 1];
873*b077aed3SPierre Pronchery             key->tls_ver = p[arg - 4] << 8 | p[arg - 3];
874*b077aed3SPierre Pronchery 
875*b077aed3SPierre Pronchery             if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
876*b077aed3SPierre Pronchery                 key->payload_length = len;
877*b077aed3SPierre Pronchery                 if (key->tls_ver >= TLS1_1_VERSION) {
878*b077aed3SPierre Pronchery                     if (len < AES_BLOCK_SIZE)
879*b077aed3SPierre Pronchery                         return 0;
880*b077aed3SPierre Pronchery                     len -= AES_BLOCK_SIZE;
881*b077aed3SPierre Pronchery                     p[arg - 2] = len >> 8;
882*b077aed3SPierre Pronchery                     p[arg - 1] = len;
883*b077aed3SPierre Pronchery                 }
884*b077aed3SPierre Pronchery 
885*b077aed3SPierre Pronchery                 return (int)(((len + SHA_DIGEST_LENGTH +
886*b077aed3SPierre Pronchery                                AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
887*b077aed3SPierre Pronchery                              - len);
888*b077aed3SPierre Pronchery             } else {
889*b077aed3SPierre Pronchery                 key->payload_length = arg;
890*b077aed3SPierre Pronchery 
891*b077aed3SPierre Pronchery                 return SHA_DIGEST_LENGTH;
892*b077aed3SPierre Pronchery             }
893*b077aed3SPierre Pronchery         }
894*b077aed3SPierre Pronchery     default:
895*b077aed3SPierre Pronchery         return -1;
896*b077aed3SPierre Pronchery     }
897*b077aed3SPierre Pronchery }
898*b077aed3SPierre Pronchery 
ossltest_rand_bytes(unsigned char * buf,int num)899e71b7053SJung-uk Kim static int ossltest_rand_bytes(unsigned char *buf, int num)
900e71b7053SJung-uk Kim {
901e71b7053SJung-uk Kim     unsigned char val = 1;
902e71b7053SJung-uk Kim 
903e71b7053SJung-uk Kim     while (--num >= 0)
904e71b7053SJung-uk Kim         *buf++ = val++;
905e71b7053SJung-uk Kim     return 1;
906e71b7053SJung-uk Kim }
907e71b7053SJung-uk Kim 
ossltest_rand_status(void)908e71b7053SJung-uk Kim static int ossltest_rand_status(void)
909e71b7053SJung-uk Kim {
910e71b7053SJung-uk Kim     return 1;
911e71b7053SJung-uk Kim }
912e71b7053SJung-uk Kim 
ossltest_rand_method(void)913e71b7053SJung-uk Kim static const RAND_METHOD *ossltest_rand_method(void)
914e71b7053SJung-uk Kim {
915e71b7053SJung-uk Kim 
916e71b7053SJung-uk Kim     static RAND_METHOD osslt_rand_meth = {
917e71b7053SJung-uk Kim         NULL,
918e71b7053SJung-uk Kim         ossltest_rand_bytes,
919e71b7053SJung-uk Kim         NULL,
920e71b7053SJung-uk Kim         NULL,
921e71b7053SJung-uk Kim         ossltest_rand_bytes,
922e71b7053SJung-uk Kim         ossltest_rand_status
923e71b7053SJung-uk Kim     };
924e71b7053SJung-uk Kim 
925e71b7053SJung-uk Kim     return &osslt_rand_meth;
926e71b7053SJung-uk Kim }
927