155714Skris/* crypto/evp/evp_lib.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8280297Sjkim *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15280297Sjkim *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22280297Sjkim *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40280297Sjkim *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52280297Sjkim *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include "cryptlib.h"
6155714Skris#include <openssl/evp.h>
6255714Skris#include <openssl/objects.h>
63290207Sjkim#ifdef OPENSSL_FIPS
64290207Sjkim# include <openssl/fips.h>
65290207Sjkim# include "evp_locl.h"
66290207Sjkim#endif
6755714Skris
6855714Skrisint EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
69280297Sjkim{
70280297Sjkim    int ret;
7155714Skris
72280297Sjkim    if (c->cipher->set_asn1_parameters != NULL)
73280297Sjkim        ret = c->cipher->set_asn1_parameters(c, type);
74290207Sjkim    else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
75291719Sjkim        switch (EVP_CIPHER_CTX_mode(c)) {
76291719Sjkim        case EVP_CIPH_WRAP_MODE:
77291719Sjkim            if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap)
78291719Sjkim                ASN1_TYPE_set(type, V_ASN1_NULL, NULL);
79290207Sjkim            ret = 1;
80291719Sjkim            break;
81291719Sjkim
82291719Sjkim        case EVP_CIPH_GCM_MODE:
83291719Sjkim        case EVP_CIPH_CCM_MODE:
84291719Sjkim        case EVP_CIPH_XTS_MODE:
85291719Sjkim            ret = -1;
86291719Sjkim            break;
87291719Sjkim
88291719Sjkim        default:
89290207Sjkim            ret = EVP_CIPHER_set_asn1_iv(c, type);
90291719Sjkim        }
91290207Sjkim    } else
92280297Sjkim        ret = -1;
93280297Sjkim    return (ret);
94280297Sjkim}
9555714Skris
9655714Skrisint EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
97280297Sjkim{
98280297Sjkim    int ret;
9955714Skris
100280297Sjkim    if (c->cipher->get_asn1_parameters != NULL)
101280297Sjkim        ret = c->cipher->get_asn1_parameters(c, type);
102290207Sjkim    else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
103291719Sjkim        switch (EVP_CIPHER_CTX_mode(c)) {
104291719Sjkim
105291719Sjkim        case EVP_CIPH_WRAP_MODE:
106291719Sjkim            ret = 1;
107291719Sjkim            break;
108291719Sjkim
109291719Sjkim        case EVP_CIPH_GCM_MODE:
110291719Sjkim        case EVP_CIPH_CCM_MODE:
111291719Sjkim        case EVP_CIPH_XTS_MODE:
112291719Sjkim            ret = -1;
113291719Sjkim            break;
114291719Sjkim
115291719Sjkim        default:
116291719Sjkim            ret = EVP_CIPHER_get_asn1_iv(c, type);
117291719Sjkim            break;
118291719Sjkim        }
119290207Sjkim    } else
120280297Sjkim        ret = -1;
121280297Sjkim    return (ret);
122280297Sjkim}
12355714Skris
12455714Skrisint EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
125280297Sjkim{
126280297Sjkim    int i = 0;
127280297Sjkim    unsigned int l;
12855714Skris
129280297Sjkim    if (type != NULL) {
130280297Sjkim        l = EVP_CIPHER_CTX_iv_length(c);
131280297Sjkim        OPENSSL_assert(l <= sizeof(c->iv));
132280297Sjkim        i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
133280297Sjkim        if (i != (int)l)
134280297Sjkim            return (-1);
135280297Sjkim        else if (i > 0)
136280297Sjkim            memcpy(c->iv, c->oiv, l);
137280297Sjkim    }
138280297Sjkim    return (i);
139280297Sjkim}
14055714Skris
14155714Skrisint EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
142280297Sjkim{
143280297Sjkim    int i = 0;
144280297Sjkim    unsigned int j;
14555714Skris
146280297Sjkim    if (type != NULL) {
147280297Sjkim        j = EVP_CIPHER_CTX_iv_length(c);
148280297Sjkim        OPENSSL_assert(j <= sizeof(c->iv));
149280297Sjkim        i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
150280297Sjkim    }
151280297Sjkim    return (i);
152280297Sjkim}
15355714Skris
15455714Skris/* Convert the various cipher NIDs and dummies to a proper OID NID */
15555714Skrisint EVP_CIPHER_type(const EVP_CIPHER *ctx)
15655714Skris{
157280297Sjkim    int nid;
158280297Sjkim    ASN1_OBJECT *otmp;
159280297Sjkim    nid = EVP_CIPHER_nid(ctx);
16055714Skris
161280297Sjkim    switch (nid) {
16255714Skris
163280297Sjkim    case NID_rc2_cbc:
164280297Sjkim    case NID_rc2_64_cbc:
165280297Sjkim    case NID_rc2_40_cbc:
16655714Skris
167280297Sjkim        return NID_rc2_cbc;
16855714Skris
169280297Sjkim    case NID_rc4:
170280297Sjkim    case NID_rc4_40:
17155714Skris
172280297Sjkim        return NID_rc4;
17355714Skris
174280297Sjkim    case NID_aes_128_cfb128:
175280297Sjkim    case NID_aes_128_cfb8:
176280297Sjkim    case NID_aes_128_cfb1:
177142425Snectar
178280297Sjkim        return NID_aes_128_cfb128;
179142425Snectar
180280297Sjkim    case NID_aes_192_cfb128:
181280297Sjkim    case NID_aes_192_cfb8:
182280297Sjkim    case NID_aes_192_cfb1:
183142425Snectar
184280297Sjkim        return NID_aes_192_cfb128;
185142425Snectar
186280297Sjkim    case NID_aes_256_cfb128:
187280297Sjkim    case NID_aes_256_cfb8:
188280297Sjkim    case NID_aes_256_cfb1:
189142425Snectar
190280297Sjkim        return NID_aes_256_cfb128;
191142425Snectar
192280297Sjkim    case NID_des_cfb64:
193280297Sjkim    case NID_des_cfb8:
194280297Sjkim    case NID_des_cfb1:
195142425Snectar
196280297Sjkim        return NID_des_cfb64;
197142425Snectar
198280297Sjkim    case NID_des_ede3_cfb64:
199280297Sjkim    case NID_des_ede3_cfb8:
200280297Sjkim    case NID_des_ede3_cfb1:
201205128Ssimon
202280297Sjkim        return NID_des_cfb64;
203205128Ssimon
204280297Sjkim    default:
205280297Sjkim        /* Check it has an OID and it is valid */
206280297Sjkim        otmp = OBJ_nid2obj(nid);
207280297Sjkim        if (!otmp || !otmp->data)
208280297Sjkim            nid = NID_undef;
209280297Sjkim        ASN1_OBJECT_free(otmp);
210280297Sjkim        return nid;
211280297Sjkim    }
21255714Skris}
21355714Skris
214167612Ssimonint EVP_CIPHER_block_size(const EVP_CIPHER *e)
215280297Sjkim{
216280297Sjkim    return e->block_size;
217280297Sjkim}
218167612Ssimon
219167612Ssimonint EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
220280297Sjkim{
221280297Sjkim    return ctx->cipher->block_size;
222280297Sjkim}
223167612Ssimon
224280297Sjkimint EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
225280297Sjkim               const unsigned char *in, unsigned int inl)
226280297Sjkim{
227280297Sjkim    return ctx->cipher->do_cipher(ctx, out, in, inl);
228280297Sjkim}
229238405Sjkim
230167612Ssimonconst EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
231280297Sjkim{
232280297Sjkim    return ctx->cipher;
233280297Sjkim}
234167612Ssimon
235167612Ssimonunsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
236280297Sjkim{
237290207Sjkim#ifdef OPENSSL_FIPS
238290207Sjkim    const EVP_CIPHER *fcipher;
239290207Sjkim    fcipher = evp_get_fips_cipher(cipher);
240290207Sjkim    if (fcipher && fcipher->flags & EVP_CIPH_FLAG_FIPS)
241290207Sjkim        return cipher->flags | EVP_CIPH_FLAG_FIPS;
242290207Sjkim#endif
243280297Sjkim    return cipher->flags;
244280297Sjkim}
245167612Ssimon
246238405Sjkimunsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
247280297Sjkim{
248290207Sjkim#ifdef OPENSSL_FIPS
249290207Sjkim    return EVP_CIPHER_flags(ctx->cipher);
250290207Sjkim#else
251280297Sjkim    return ctx->cipher->flags;
252290207Sjkim#endif
253280297Sjkim}
254238405Sjkim
255167612Ssimonvoid *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
256280297Sjkim{
257280297Sjkim    return ctx->app_data;
258280297Sjkim}
259167612Ssimon
260167612Ssimonvoid EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
261280297Sjkim{
262280297Sjkim    ctx->app_data = data;
263280297Sjkim}
264167612Ssimon
265167612Ssimonint EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
266280297Sjkim{
267280297Sjkim    return cipher->iv_len;
268280297Sjkim}
269167612Ssimon
270238405Sjkimint EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
271280297Sjkim{
272280297Sjkim    return ctx->cipher->iv_len;
273280297Sjkim}
274238405Sjkim
275167612Ssimonint EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
276280297Sjkim{
277280297Sjkim    return cipher->key_len;
278280297Sjkim}
279167612Ssimon
280167612Ssimonint EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
281280297Sjkim{
282280297Sjkim    return ctx->key_len;
283280297Sjkim}
284167612Ssimon
285238405Sjkimint EVP_CIPHER_nid(const EVP_CIPHER *cipher)
286280297Sjkim{
287280297Sjkim    return cipher->nid;
288280297Sjkim}
289238405Sjkim
290167612Ssimonint EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
291280297Sjkim{
292280297Sjkim    return ctx->cipher->nid;
293280297Sjkim}
294167612Ssimon
295280297Sjkimint EVP_MD_block_size(const EVP_MD *md)
296280297Sjkim{
297280297Sjkim    return md->block_size;
298280297Sjkim}
299167612Ssimon
300167612Ssimonint EVP_MD_type(const EVP_MD *md)
301280297Sjkim{
302280297Sjkim    return md->type;
303280297Sjkim}
304167612Ssimon
305167612Ssimonint EVP_MD_pkey_type(const EVP_MD *md)
306280297Sjkim{
307280297Sjkim    return md->pkey_type;
308280297Sjkim}
309167612Ssimon
310167612Ssimonint EVP_MD_size(const EVP_MD *md)
311280297Sjkim{
312280297Sjkim    if (!md) {
313280297Sjkim        EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
314280297Sjkim        return -1;
315280297Sjkim    }
316280297Sjkim    return md->md_size;
317280297Sjkim}
318167612Ssimon
319290207Sjkim#ifdef OPENSSL_FIPS
320290207Sjkim
321290207Sjkimconst EVP_MD *evp_get_fips_md(const EVP_MD *md)
322290207Sjkim{
323290207Sjkim    int nid = EVP_MD_type(md);
324290207Sjkim    if (nid == NID_dsa)
325290207Sjkim        return FIPS_evp_dss1();
326290207Sjkim    else if (nid == NID_dsaWithSHA)
327290207Sjkim        return FIPS_evp_dss();
328290207Sjkim    else if (nid == NID_ecdsa_with_SHA1)
329290207Sjkim        return FIPS_evp_ecdsa();
330290207Sjkim    else
331290207Sjkim        return FIPS_get_digestbynid(nid);
332290207Sjkim}
333290207Sjkim
334290207Sjkimconst EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher)
335290207Sjkim{
336290207Sjkim    int nid = cipher->nid;
337290207Sjkim    if (nid == NID_undef)
338290207Sjkim        return FIPS_evp_enc_null();
339290207Sjkim    else
340290207Sjkim        return FIPS_get_cipherbynid(nid);
341290207Sjkim}
342290207Sjkim
343290207Sjkim#endif
344290207Sjkim
345238405Sjkimunsigned long EVP_MD_flags(const EVP_MD *md)
346280297Sjkim{
347290207Sjkim#ifdef OPENSSL_FIPS
348290207Sjkim    const EVP_MD *fmd;
349290207Sjkim    fmd = evp_get_fips_md(md);
350290207Sjkim    if (fmd && fmd->flags & EVP_MD_FLAG_FIPS)
351290207Sjkim        return md->flags | EVP_MD_FLAG_FIPS;
352290207Sjkim#endif
353280297Sjkim    return md->flags;
354280297Sjkim}
355238405Sjkim
356238405Sjkimconst EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
357280297Sjkim{
358280297Sjkim    if (!ctx)
359280297Sjkim        return NULL;
360280297Sjkim    return ctx->digest;
361280297Sjkim}
362167612Ssimon
363167612Ssimonvoid EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
364280297Sjkim{
365280297Sjkim    ctx->flags |= flags;
366280297Sjkim}
367167612Ssimon
368167612Ssimonvoid EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
369280297Sjkim{
370280297Sjkim    ctx->flags &= ~flags;
371280297Sjkim}
372167612Ssimon
373167612Ssimonint EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
374280297Sjkim{
375280297Sjkim    return (ctx->flags & flags);
376280297Sjkim}
377194206Ssimon
378194206Ssimonvoid EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
379280297Sjkim{
380280297Sjkim    ctx->flags |= flags;
381280297Sjkim}
382194206Ssimon
383194206Ssimonvoid EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
384280297Sjkim{
385280297Sjkim    ctx->flags &= ~flags;
386280297Sjkim}
387194206Ssimon
388194206Ssimonint EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
389280297Sjkim{
390280297Sjkim    return (ctx->flags & flags);
391280297Sjkim}
392