~cyphermox/shim/0.9git

« back to all changes in this revision

Viewing changes to Cryptlib/OpenSSL/crypto/asn1/p5_pbev2.c

  • Committer: Mathieu Trudel-Lapierre
  • Date: 2016-07-26 16:03:25 UTC
  • mfrom: (0.1.7)
  • Revision ID: mathieu.trudel-lapierre@canonical.com-20160726160325-y702pvbyiy4t2buq
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* p5_pbev2.c */
2
 
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 
 * project 1999-2004.
 
2
/*
 
3
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
 
4
 * 1999-2004.
4
5
 */
5
6
/* ====================================================================
6
7
 * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
10
11
 * are met:
11
12
 *
12
13
 * 1. Redistributions of source code must retain the above copyright
13
 
 *    notice, this list of conditions and the following disclaimer. 
 
14
 *    notice, this list of conditions and the following disclaimer.
14
15
 *
15
16
 * 2. Redistributions in binary form must reproduce the above copyright
16
17
 *    notice, this list of conditions and the following disclaimer in
65
66
/* PKCS#5 v2.0 password based encryption structures */
66
67
 
67
68
ASN1_SEQUENCE(PBE2PARAM) = {
68
 
        ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
69
 
        ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
 
69
        ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
 
70
        ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
70
71
} ASN1_SEQUENCE_END(PBE2PARAM)
71
72
 
72
73
IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
73
74
 
74
75
ASN1_SEQUENCE(PBKDF2PARAM) = {
75
 
        ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
76
 
        ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
77
 
        ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
78
 
        ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
 
76
        ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
 
77
        ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
 
78
        ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
 
79
        ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
79
80
} ASN1_SEQUENCE_END(PBKDF2PARAM)
80
81
 
81
82
IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
82
83
 
83
 
/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm:
84
 
 * yes I know this is horrible!
 
84
/*
 
85
 * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
 
86
 * this is horrible! Extended version to allow application supplied PRF NID
 
87
 * and IV.
85
88
 */
86
89
 
 
90
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
 
91
                              unsigned char *salt, int saltlen,
 
92
                              unsigned char *aiv, int prf_nid)
 
93
{
 
94
    X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
 
95
    int alg_nid, keylen;
 
96
    EVP_CIPHER_CTX ctx;
 
97
    unsigned char iv[EVP_MAX_IV_LENGTH];
 
98
    PBE2PARAM *pbe2 = NULL;
 
99
    ASN1_OBJECT *obj;
 
100
 
 
101
    alg_nid = EVP_CIPHER_type(cipher);
 
102
    if (alg_nid == NID_undef) {
 
103
        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
 
104
                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
 
105
        goto err;
 
106
    }
 
107
    obj = OBJ_nid2obj(alg_nid);
 
108
 
 
109
    if (!(pbe2 = PBE2PARAM_new()))
 
110
        goto merr;
 
111
 
 
112
    /* Setup the AlgorithmIdentifier for the encryption scheme */
 
113
    scheme = pbe2->encryption;
 
114
 
 
115
    scheme->algorithm = obj;
 
116
    if (!(scheme->parameter = ASN1_TYPE_new()))
 
117
        goto merr;
 
118
 
 
119
    /* Create random IV */
 
120
    if (EVP_CIPHER_iv_length(cipher)) {
 
121
        if (aiv)
 
122
            memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
 
123
        else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
 
124
            goto err;
 
125
    }
 
126
 
 
127
    EVP_CIPHER_CTX_init(&ctx);
 
128
 
 
129
    /* Dummy cipherinit to just setup the IV, and PRF */
 
130
    if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
 
131
        goto err;
 
132
    if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
 
133
        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
 
134
        EVP_CIPHER_CTX_cleanup(&ctx);
 
135
        goto err;
 
136
    }
 
137
    /*
 
138
     * If prf NID unspecified see if cipher has a preference. An error is OK
 
139
     * here: just means use default PRF.
 
140
     */
 
141
    if ((prf_nid == -1) &&
 
142
        EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
 
143
        ERR_clear_error();
 
144
        prf_nid = NID_hmacWithSHA1;
 
145
    }
 
146
    EVP_CIPHER_CTX_cleanup(&ctx);
 
147
 
 
148
    /* If its RC2 then we'd better setup the key length */
 
149
 
 
150
    if (alg_nid == NID_rc2_cbc)
 
151
        keylen = EVP_CIPHER_key_length(cipher);
 
152
    else
 
153
        keylen = -1;
 
154
 
 
155
    /* Setup keyfunc */
 
156
 
 
157
    X509_ALGOR_free(pbe2->keyfunc);
 
158
 
 
159
    pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
 
160
 
 
161
    if (!pbe2->keyfunc)
 
162
        goto merr;
 
163
 
 
164
    /* Now set up top level AlgorithmIdentifier */
 
165
 
 
166
    if (!(ret = X509_ALGOR_new()))
 
167
        goto merr;
 
168
    if (!(ret->parameter = ASN1_TYPE_new()))
 
169
        goto merr;
 
170
 
 
171
    ret->algorithm = OBJ_nid2obj(NID_pbes2);
 
172
 
 
173
    /* Encode PBE2PARAM into parameter */
 
174
 
 
175
    if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
 
176
                        &ret->parameter->value.sequence))
 
177
         goto merr;
 
178
    ret->parameter->type = V_ASN1_SEQUENCE;
 
179
 
 
180
    PBE2PARAM_free(pbe2);
 
181
    pbe2 = NULL;
 
182
 
 
183
    return ret;
 
184
 
 
185
 merr:
 
186
    ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);
 
187
 
 
188
 err:
 
189
    PBE2PARAM_free(pbe2);
 
190
    /* Note 'scheme' is freed as part of pbe2 */
 
191
    X509_ALGOR_free(kalg);
 
192
    X509_ALGOR_free(ret);
 
193
 
 
194
    return NULL;
 
195
 
 
196
}
 
197
 
87
198
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
88
 
                                 unsigned char *salt, int saltlen)
89
 
{
90
 
        X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
91
 
        int alg_nid;
92
 
        EVP_CIPHER_CTX ctx;
93
 
        unsigned char iv[EVP_MAX_IV_LENGTH];
94
 
        PBKDF2PARAM *kdf = NULL;
95
 
        PBE2PARAM *pbe2 = NULL;
96
 
        ASN1_OCTET_STRING *osalt = NULL;
97
 
        ASN1_OBJECT *obj;
98
 
 
99
 
        alg_nid = EVP_CIPHER_type(cipher);
100
 
        if(alg_nid == NID_undef) {
101
 
                ASN1err(ASN1_F_PKCS5_PBE2_SET,
102
 
                                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
103
 
                goto err;
104
 
        }
105
 
        obj = OBJ_nid2obj(alg_nid);
106
 
 
107
 
        if(!(pbe2 = PBE2PARAM_new())) goto merr;
108
 
 
109
 
        /* Setup the AlgorithmIdentifier for the encryption scheme */
110
 
        scheme = pbe2->encryption;
111
 
 
112
 
        scheme->algorithm = obj;
113
 
        if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;
114
 
 
115
 
        /* Create random IV */
116
 
        if (EVP_CIPHER_iv_length(cipher) &&
117
 
                RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
118
 
                goto err;
119
 
 
120
 
        EVP_CIPHER_CTX_init(&ctx);
121
 
 
122
 
        /* Dummy cipherinit to just setup the IV */
123
 
        EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
124
 
        if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
125
 
                ASN1err(ASN1_F_PKCS5_PBE2_SET,
126
 
                                        ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
127
 
                EVP_CIPHER_CTX_cleanup(&ctx);
128
 
                goto err;
129
 
        }
130
 
        EVP_CIPHER_CTX_cleanup(&ctx);
131
 
 
132
 
        if(!(kdf = PBKDF2PARAM_new())) goto merr;
133
 
        if(!(osalt = M_ASN1_OCTET_STRING_new())) goto merr;
134
 
 
135
 
        if (!saltlen) saltlen = PKCS5_SALT_LEN;
136
 
        if (!(osalt->data = OPENSSL_malloc (saltlen))) goto merr;
137
 
        osalt->length = saltlen;
138
 
        if (salt) memcpy (osalt->data, salt, saltlen);
139
 
        else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0) goto merr;
140
 
 
141
 
        if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
142
 
        if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr;
143
 
 
144
 
        /* Now include salt in kdf structure */
145
 
        kdf->salt->value.octet_string = osalt;
146
 
        kdf->salt->type = V_ASN1_OCTET_STRING;
147
 
        osalt = NULL;
148
 
 
149
 
        /* If its RC2 then we'd better setup the key length */
150
 
 
151
 
        if(alg_nid == NID_rc2_cbc) {
152
 
                if(!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr;
153
 
                if(!ASN1_INTEGER_set (kdf->keylength,
154
 
                                 EVP_CIPHER_key_length(cipher))) goto merr;
155
 
        }
156
 
 
157
 
        /* prf can stay NULL because we are using hmacWithSHA1 */
158
 
 
159
 
        /* Now setup the PBE2PARAM keyfunc structure */
160
 
 
161
 
        pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
162
 
 
163
 
        /* Encode PBKDF2PARAM into parameter of pbe2 */
164
 
 
165
 
        if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;
166
 
 
167
 
        if(!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM,
168
 
                         &pbe2->keyfunc->parameter->value.sequence)) goto merr;
169
 
        pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;
170
 
 
171
 
        PBKDF2PARAM_free(kdf);
172
 
        kdf = NULL;
173
 
 
174
 
        /* Now set up top level AlgorithmIdentifier */
175
 
 
176
 
        if(!(ret = X509_ALGOR_new())) goto merr;
177
 
        if(!(ret->parameter = ASN1_TYPE_new())) goto merr;
178
 
 
179
 
        ret->algorithm = OBJ_nid2obj(NID_pbes2);
180
 
 
181
 
        /* Encode PBE2PARAM into parameter */
182
 
 
183
 
        if(!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM,
184
 
                                 &ret->parameter->value.sequence)) goto merr;
185
 
        ret->parameter->type = V_ASN1_SEQUENCE;
186
 
 
187
 
        PBE2PARAM_free(pbe2);
188
 
        pbe2 = NULL;
189
 
 
190
 
        return ret;
191
 
 
192
 
        merr:
193
 
        ASN1err(ASN1_F_PKCS5_PBE2_SET,ERR_R_MALLOC_FAILURE);
194
 
 
195
 
        err:
196
 
        PBE2PARAM_free(pbe2);
197
 
        /* Note 'scheme' is freed as part of pbe2 */
198
 
        M_ASN1_OCTET_STRING_free(osalt);
199
 
        PBKDF2PARAM_free(kdf);
200
 
        X509_ALGOR_free(kalg);
201
 
        X509_ALGOR_free(ret);
202
 
 
203
 
        return NULL;
204
 
 
 
199
                           unsigned char *salt, int saltlen)
 
200
{
 
201
    return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
 
202
}
 
203
 
 
204
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
 
205
                             int prf_nid, int keylen)
 
206
{
 
207
    X509_ALGOR *keyfunc = NULL;
 
208
    PBKDF2PARAM *kdf = NULL;
 
209
    ASN1_OCTET_STRING *osalt = NULL;
 
210
 
 
211
    if (!(kdf = PBKDF2PARAM_new()))
 
212
        goto merr;
 
213
    if (!(osalt = M_ASN1_OCTET_STRING_new()))
 
214
        goto merr;
 
215
 
 
216
    kdf->salt->value.octet_string = osalt;
 
217
    kdf->salt->type = V_ASN1_OCTET_STRING;
 
218
 
 
219
    if (!saltlen)
 
220
        saltlen = PKCS5_SALT_LEN;
 
221
    if (!(osalt->data = OPENSSL_malloc(saltlen)))
 
222
        goto merr;
 
223
 
 
224
    osalt->length = saltlen;
 
225
 
 
226
    if (salt)
 
227
        memcpy(osalt->data, salt, saltlen);
 
228
    else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0)
 
229
        goto merr;
 
230
 
 
231
    if (iter <= 0)
 
232
        iter = PKCS5_DEFAULT_ITER;
 
233
 
 
234
    if (!ASN1_INTEGER_set(kdf->iter, iter))
 
235
        goto merr;
 
236
 
 
237
    /* If have a key len set it up */
 
238
 
 
239
    if (keylen > 0) {
 
240
        if (!(kdf->keylength = M_ASN1_INTEGER_new()))
 
241
            goto merr;
 
242
        if (!ASN1_INTEGER_set(kdf->keylength, keylen))
 
243
            goto merr;
 
244
    }
 
245
 
 
246
    /* prf can stay NULL if we are using hmacWithSHA1 */
 
247
    if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
 
248
        kdf->prf = X509_ALGOR_new();
 
249
        if (!kdf->prf)
 
250
            goto merr;
 
251
        X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
 
252
    }
 
253
 
 
254
    /* Finally setup the keyfunc structure */
 
255
 
 
256
    keyfunc = X509_ALGOR_new();
 
257
    if (!keyfunc)
 
258
        goto merr;
 
259
 
 
260
    keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
 
261
 
 
262
    /* Encode PBKDF2PARAM into parameter of pbe2 */
 
263
 
 
264
    if (!(keyfunc->parameter = ASN1_TYPE_new()))
 
265
        goto merr;
 
266
 
 
267
    if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
 
268
                        &keyfunc->parameter->value.sequence))
 
269
         goto merr;
 
270
    keyfunc->parameter->type = V_ASN1_SEQUENCE;
 
271
 
 
272
    PBKDF2PARAM_free(kdf);
 
273
    return keyfunc;
 
274
 
 
275
 merr:
 
276
    ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
 
277
    PBKDF2PARAM_free(kdf);
 
278
    X509_ALGOR_free(keyfunc);
 
279
    return NULL;
205
280
}