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