Branch data Line data Source code
1 : : /* crypto/cms/cms_kari.c */
2 : : /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 : : * project.
4 : : */
5 : : /* ====================================================================
6 : : * Copyright (c) 2013 The OpenSSL Project. All rights reserved.
7 : : *
8 : : * Redistribution and use in source and binary forms, with or without
9 : : * modification, are permitted provided that the following conditions
10 : : * are met:
11 : : *
12 : : * 1. Redistributions of source code must retain the above copyright
13 : : * notice, this list of conditions and the following disclaimer.
14 : : *
15 : : * 2. Redistributions in binary form must reproduce the above copyright
16 : : * notice, this list of conditions and the following disclaimer in
17 : : * the documentation and/or other materials provided with the
18 : : * distribution.
19 : : *
20 : : * 3. All advertising materials mentioning features or use of this
21 : : * software must display the following acknowledgment:
22 : : * "This product includes software developed by the OpenSSL Project
23 : : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 : : *
25 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 : : * endorse or promote products derived from this software without
27 : : * prior written permission. For written permission, please contact
28 : : * licensing@OpenSSL.org.
29 : : *
30 : : * 5. Products derived from this software may not be called "OpenSSL"
31 : : * nor may "OpenSSL" appear in their names without prior written
32 : : * permission of the OpenSSL Project.
33 : : *
34 : : * 6. Redistributions of any form whatsoever must retain the following
35 : : * acknowledgment:
36 : : * "This product includes software developed by the OpenSSL Project
37 : : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 : : *
39 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
51 : : * ====================================================================
52 : : */
53 : :
54 : : #include "cryptlib.h"
55 : : #include <openssl/asn1t.h>
56 : : #include <openssl/pem.h>
57 : : #include <openssl/x509v3.h>
58 : : #include <openssl/err.h>
59 : : #include <openssl/cms.h>
60 : : #include <openssl/rand.h>
61 : : #include <openssl/aes.h>
62 : : #include "cms_lcl.h"
63 : : #include "asn1_locl.h"
64 : :
65 : : DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo)
66 : : DECLARE_ASN1_ITEM(CMS_RecipientEncryptedKey)
67 : : DECLARE_ASN1_ITEM(CMS_OriginatorPublicKey)
68 : :
69 : : /* Key Agreement Recipient Info (KARI) routines */
70 : :
71 : 8 : int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
72 : : X509_ALGOR **palg,
73 : : ASN1_OCTET_STRING **pukm)
74 : : {
75 [ - + ]: 8 : if (ri->type != CMS_RECIPINFO_AGREE)
76 : : {
77 : 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG,
78 : : CMS_R_NOT_KEY_AGREEMENT);
79 : 0 : return 0;
80 : : }
81 [ + - ]: 8 : if (palg)
82 : 8 : *palg = ri->d.kari->keyEncryptionAlgorithm;
83 [ + - ]: 8 : if (pukm)
84 : 8 : *pukm = ri->d.kari->ukm;
85 : : return 1;
86 : : }
87 : :
88 : : /* Retrieve recipient encrypted keys from a kari */
89 : :
90 : 4 : STACK_OF(CMS_RecipientEncryptedKey) *CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
91 : : {
92 [ - + ]: 4 : if (ri->type != CMS_RECIPINFO_AGREE)
93 : : {
94 : 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS,
95 : : CMS_R_NOT_KEY_AGREEMENT);
96 : 0 : return NULL;
97 : : }
98 : 4 : return ri->d.kari->recipientEncryptedKeys;
99 : : }
100 : :
101 : 8 : int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
102 : : X509_ALGOR **pubalg,
103 : : ASN1_BIT_STRING **pubkey,
104 : : ASN1_OCTET_STRING **keyid,
105 : : X509_NAME **issuer, ASN1_INTEGER **sno)
106 : : {
107 : : CMS_OriginatorIdentifierOrKey *oik;
108 [ - + ]: 8 : if (ri->type != CMS_RECIPINFO_AGREE)
109 : : {
110 : 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID,
111 : : CMS_R_NOT_KEY_AGREEMENT);
112 : 0 : return 0;
113 : : }
114 : 8 : oik = ri->d.kari->originator;
115 [ - + ]: 8 : if (issuer)
116 : 0 : *issuer = NULL;
117 [ - + ]: 8 : if (sno)
118 : 0 : *sno = NULL;
119 [ - + ]: 8 : if (keyid)
120 : 0 : *keyid = NULL;
121 [ + - ]: 8 : if (pubalg)
122 : 8 : *pubalg = NULL;
123 [ + - ]: 8 : if (pubkey)
124 : 8 : *pubkey = NULL;
125 [ - + ]: 8 : if (oik->type == CMS_OIK_ISSUER_SERIAL)
126 : : {
127 [ # # ]: 0 : if (issuer)
128 : 0 : *issuer = oik->d.issuerAndSerialNumber->issuer;
129 [ # # ]: 0 : if (sno)
130 : 0 : *sno = oik->d.issuerAndSerialNumber->serialNumber;
131 : : }
132 [ - + ]: 8 : else if (oik->type == CMS_OIK_KEYIDENTIFIER)
133 : : {
134 [ # # ]: 0 : if (keyid)
135 : 0 : *keyid = oik->d.subjectKeyIdentifier;
136 : : }
137 [ + - ]: 8 : else if (oik->type == CMS_OIK_PUBKEY)
138 : : {
139 [ + - ]: 8 : if (pubalg)
140 : 8 : *pubalg = oik->d.originatorKey->algorithm;
141 [ + - ]: 8 : if (pubkey)
142 : 8 : *pubkey = oik->d.originatorKey->publicKey;
143 : : }
144 : : else
145 : : return 0;
146 : : return 1;
147 : : }
148 : :
149 : 0 : int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
150 : : {
151 : : CMS_OriginatorIdentifierOrKey *oik;
152 [ # # ]: 0 : if (ri->type != CMS_RECIPINFO_AGREE)
153 : : {
154 : 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP,
155 : : CMS_R_NOT_KEY_AGREEMENT);
156 : 0 : return -2;
157 : : }
158 : 0 : oik = ri->d.kari->originator;
159 [ # # ]: 0 : if (oik->type == CMS_OIK_ISSUER_SERIAL)
160 : 0 : return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
161 [ # # ]: 0 : else if (oik->type == CMS_OIK_KEYIDENTIFIER)
162 : 0 : return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
163 : : return -1;
164 : : }
165 : :
166 : 0 : int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
167 : : ASN1_OCTET_STRING **keyid,
168 : : ASN1_GENERALIZEDTIME **tm,
169 : : CMS_OtherKeyAttribute **other,
170 : : X509_NAME **issuer, ASN1_INTEGER **sno)
171 : : {
172 : 0 : CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
173 [ # # ]: 0 : if (rid->type == CMS_REK_ISSUER_SERIAL)
174 : : {
175 [ # # ]: 0 : if (issuer)
176 : 0 : *issuer = rid->d.issuerAndSerialNumber->issuer;
177 [ # # ]: 0 : if (sno)
178 : 0 : *sno = rid->d.issuerAndSerialNumber->serialNumber;
179 [ # # ]: 0 : if (keyid)
180 : 0 : *keyid = NULL;
181 [ # # ]: 0 : if (tm)
182 : 0 : *tm = NULL;
183 [ # # ]: 0 : if (other)
184 : 0 : *other = NULL;
185 : : }
186 [ # # ]: 0 : else if (rid->type == CMS_REK_KEYIDENTIFIER)
187 : : {
188 [ # # ]: 0 : if (keyid)
189 : 0 : *keyid = rid->d.rKeyId->subjectKeyIdentifier;
190 [ # # ]: 0 : if (tm)
191 : 0 : *tm = rid->d.rKeyId->date;
192 [ # # ]: 0 : if (other)
193 : 0 : *other = rid->d.rKeyId->other;
194 [ # # ]: 0 : if (issuer)
195 : 0 : *issuer = NULL;
196 [ # # ]: 0 : if (sno)
197 : 0 : *sno = NULL;
198 : : }
199 : : else
200 : : return 0;
201 : : return 1;
202 : : }
203 : :
204 : 4 : int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
205 : : X509 *cert)
206 : : {
207 : 4 : CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
208 [ + - ]: 4 : if (rid->type == CMS_REK_ISSUER_SERIAL)
209 : 4 : return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
210 [ # # ]: 0 : else if (rid->type == CMS_REK_KEYIDENTIFIER)
211 : 0 : return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert);
212 : : else
213 : : return -1;
214 : : }
215 : :
216 : 8 : int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
217 : : {
218 : : EVP_PKEY_CTX *pctx;
219 : 8 : CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
220 [ - + ]: 8 : if (kari->pctx)
221 : : {
222 : 0 : EVP_PKEY_CTX_free(kari->pctx);
223 : 0 : kari->pctx = NULL;
224 : : }
225 [ + + ]: 8 : if (!pk)
226 : : return 1;
227 : 4 : pctx = EVP_PKEY_CTX_new(pk, NULL);
228 [ + - ][ + - ]: 4 : if (!pctx || !EVP_PKEY_derive_init(pctx))
229 : : goto err;
230 : 4 : kari->pctx = pctx;
231 : 4 : return 1;
232 : : err:
233 [ # # ]: 0 : if (pctx)
234 : 0 : EVP_PKEY_CTX_free(pctx);
235 : : return 0;
236 : : }
237 : :
238 : 8 : EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
239 : : {
240 [ + - ]: 8 : if (ri->type == CMS_RECIPINFO_AGREE)
241 : 8 : return &ri->d.kari->ctx;
242 : : return NULL;
243 : : }
244 : :
245 : : /* Derive KEK and decrypt/encrypt with it to produce either the
246 : : * original CEK or the encrypted CEK.
247 : : */
248 : :
249 : 8 : static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
250 : : const unsigned char *in, size_t inlen,
251 : : CMS_KeyAgreeRecipientInfo *kari, int enc)
252 : : {
253 : : /* Key encryption key */
254 : : unsigned char kek[EVP_MAX_KEY_LENGTH];
255 : : size_t keklen;
256 : 8 : int rv = 0;
257 : 8 : unsigned char *out = NULL;
258 : : int outlen;
259 : 8 : keklen = EVP_CIPHER_CTX_key_length(&kari->ctx);
260 [ + - ]: 8 : if (keklen > EVP_MAX_KEY_LENGTH)
261 : : return 0;
262 : : /* Derive KEK */
263 [ + - ]: 8 : if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
264 : : goto err;
265 : : /* Set KEK in context */
266 [ + - ]: 8 : if (!EVP_CipherInit_ex(&kari->ctx, NULL, NULL, kek, NULL, enc))
267 : : goto err;
268 : : /* obtain output length of ciphered key */
269 [ + - ]: 8 : if (!EVP_CipherUpdate(&kari->ctx, NULL, &outlen, in, inlen))
270 : : goto err;
271 : 8 : out = OPENSSL_malloc(outlen);
272 [ + - ]: 8 : if (!out)
273 : : goto err;
274 [ + - ]: 8 : if (!EVP_CipherUpdate(&kari->ctx, out, &outlen, in, inlen))
275 : : goto err;
276 : 8 : *pout = out;
277 : 8 : *poutlen = (size_t)outlen;
278 : 8 : rv = 1;
279 : :
280 : : err:
281 : 8 : OPENSSL_cleanse(kek, keklen);
282 [ - + ]: 8 : if (!rv && out)
283 : 0 : OPENSSL_free(out);
284 : 8 : EVP_CIPHER_CTX_cleanup(&kari->ctx);
285 : 8 : EVP_PKEY_CTX_free(kari->pctx);
286 : 8 : kari->pctx = NULL;
287 : 8 : return rv;
288 : : }
289 : :
290 : 4 : int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
291 : : CMS_RecipientEncryptedKey *rek)
292 : : {
293 : 4 : int rv = 0;
294 : 4 : unsigned char *enckey = NULL, *cek = NULL;
295 : : size_t enckeylen;
296 : : size_t ceklen;
297 : : CMS_EncryptedContentInfo *ec;
298 : 4 : enckeylen = rek->encryptedKey->length;
299 : 4 : enckey = rek->encryptedKey->data;
300 : : /* Setup all parameters to derive KEK */
301 [ + - ]: 4 : if (!cms_env_asn1_ctrl(ri, 1))
302 : : goto err;
303 : : /* Attempt to decrypt CEK */
304 [ + - ]: 4 : if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
305 : : goto err;
306 : 4 : ec = cms->d.envelopedData->encryptedContentInfo;
307 [ - + ]: 4 : if (ec->key)
308 : : {
309 : 0 : OPENSSL_cleanse(ec->key, ec->keylen);
310 : 0 : OPENSSL_free(ec->key);
311 : : }
312 : 4 : ec->key = cek;
313 : 4 : ec->keylen = ceklen;
314 : 4 : cek = NULL;
315 : 4 : rv = 1;
316 : : err:
317 [ - + ]: 4 : if (cek)
318 : 0 : OPENSSL_free(cek);
319 : 4 : return rv;
320 : : }
321 : :
322 : : /* Create ephemeral key and initialise context based on it */
323 : 8 : static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
324 : : EVP_PKEY *pk)
325 : : {
326 : 4 : EVP_PKEY_CTX *pctx = NULL;
327 : 4 : EVP_PKEY *ekey = NULL;
328 : 4 : int rv = 0;
329 : 4 : pctx = EVP_PKEY_CTX_new(pk, NULL);
330 [ + - ]: 4 : if (!pctx)
331 : : goto err;
332 [ + - ]: 4 : if (EVP_PKEY_keygen_init(pctx) <= 0)
333 : : goto err;
334 [ + - ]: 4 : if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
335 : : goto err;
336 : 4 : EVP_PKEY_CTX_free(pctx);
337 : 4 : pctx = EVP_PKEY_CTX_new(ekey, NULL);
338 [ + - ]: 4 : if (!pctx)
339 : : goto err;
340 [ + - ]: 4 : if (EVP_PKEY_derive_init(pctx) <= 0)
341 : : goto err;
342 : 4 : kari->pctx = pctx;
343 : 4 : rv = 1;
344 : : err:
345 [ - + ]: 4 : if (!rv && pctx)
346 : 0 : EVP_PKEY_CTX_free(pctx);
347 [ + - ]: 4 : if (ekey)
348 : 4 : EVP_PKEY_free(ekey);
349 : 4 : return rv;
350 : : }
351 : :
352 : : /* Initialise a ktri based on passed certificate and key */
353 : :
354 : 4 : int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
355 : : EVP_PKEY *pk, unsigned int flags)
356 : : {
357 : : CMS_KeyAgreeRecipientInfo *kari;
358 : 4 : CMS_RecipientEncryptedKey *rek = NULL;
359 : :
360 : 4 : ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
361 [ + - ]: 4 : if (!ri->d.kari)
362 : : return 0;
363 : 4 : ri->type = CMS_RECIPINFO_AGREE;
364 : :
365 : 4 : kari = ri->d.kari;
366 : 4 : kari->version = 3;
367 : :
368 : 4 : rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
369 [ - + ]: 4 : if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek))
370 : : {
371 : 0 : M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
372 : 0 : return 0;
373 : : }
374 : :
375 [ - + ]: 4 : if (flags & CMS_USE_KEYID)
376 : : {
377 : 0 : rek->rid->type = CMS_REK_KEYIDENTIFIER;
378 [ # # ]: 0 : if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
379 : : return 0;
380 : : }
381 : : else
382 : : {
383 : 4 : rek->rid->type = CMS_REK_ISSUER_SERIAL;
384 [ + - ]: 4 : if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
385 : : return 0;
386 : : }
387 : :
388 : : /* Create ephemeral key */
389 [ + - ]: 4 : if (!cms_kari_create_ephemeral_key(kari, pk))
390 : : return 0;
391 : :
392 : 4 : CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
393 : 4 : rek->pkey = pk;
394 : 4 : return 1;
395 : : }
396 : :
397 : 4 : static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
398 : : const EVP_CIPHER *cipher)
399 : : {
400 : 4 : EVP_CIPHER_CTX *ctx = &kari->ctx;
401 : : const EVP_CIPHER *kekcipher;
402 : 4 : int keylen = EVP_CIPHER_key_length(cipher);
403 : : /* If a suitable wrap algorithm is already set nothing to do */
404 : 4 : kekcipher = EVP_CIPHER_CTX_cipher(ctx);
405 : :
406 [ - + ]: 4 : if (kekcipher)
407 : : {
408 [ # # ]: 0 : if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE)
409 : : return 0;
410 : 0 : return 1;
411 : : }
412 : : /* Pick a cipher based on content encryption cipher. If it is
413 : : * DES3 use DES3 wrap otherwise use AES wrap similar to key
414 : : * size.
415 : : */
416 [ + + ]: 4 : if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
417 : 1 : kekcipher = EVP_des_ede3_wrap();
418 [ + - ]: 3 : else if (keylen <= 16)
419 : 3 : kekcipher = EVP_aes_128_wrap();
420 [ # # ]: 0 : else if (keylen <= 24)
421 : 0 : kekcipher = EVP_aes_192_wrap();
422 : : else
423 : 0 : kekcipher = EVP_aes_256_wrap();
424 : 4 : return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);
425 : : }
426 : :
427 : : /* Encrypt content key in key agreement recipient info */
428 : :
429 : 4 : int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
430 : : {
431 : : CMS_KeyAgreeRecipientInfo *kari;
432 : : CMS_EncryptedContentInfo *ec;
433 : : CMS_RecipientEncryptedKey *rek;
434 : : STACK_OF(CMS_RecipientEncryptedKey) *reks;
435 : : int i;
436 : :
437 [ - + ]: 4 : if (ri->type != CMS_RECIPINFO_AGREE)
438 : : {
439 : 0 : CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT,
440 : : CMS_R_NOT_KEY_AGREEMENT);
441 : 0 : return 0;
442 : : }
443 : 4 : kari = ri->d.kari;
444 : 4 : reks = kari->recipientEncryptedKeys;
445 : 4 : ec = cms->d.envelopedData->encryptedContentInfo;
446 : : /* Initialise wrap algorithm parameters */
447 [ + - ]: 4 : if (!cms_wrap_init(kari, ec->cipher))
448 : : return 0;
449 : : /* If no orignator key set up initialise for ephemeral key
450 : : * the public key ASN1 structure will set the actual public
451 : : * key value.
452 : : */
453 [ + - ]: 4 : if (kari->originator->type == -1)
454 : : {
455 : 4 : CMS_OriginatorIdentifierOrKey *oik = kari->originator;
456 : 4 : oik->type = CMS_OIK_PUBKEY;
457 : 4 : oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
458 [ + - ]: 4 : if (!oik->d.originatorKey)
459 : : return 0;
460 : : }
461 : : /* Initialise KDF algorithm */
462 [ + - ]: 4 : if (!cms_env_asn1_ctrl(ri, 0))
463 : : return 0;
464 : : /* For each rek, derive KEK, encrypt CEK */
465 [ + + ]: 8 : for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++)
466 : : {
467 : : unsigned char *enckey;
468 : : size_t enckeylen;
469 : 4 : rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
470 [ + - ]: 4 : if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
471 : 0 : return 0;
472 [ + - ]: 4 : if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
473 : : kari, 1))
474 : : return 0;
475 : 4 : ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen);
476 : : }
477 : :
478 : : return 1;
479 : :
480 : : }
|