]>
Commit | Line | Data |
---|---|---|
d1e348cf A |
1 | /* $NetBSD: crypto_openssl.c,v 1.11.6.1 2006/12/18 10:18:10 vanhu Exp $ */ |
2 | ||
3 | /* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */ | |
52b7d2ce A |
4 | |
5 | /* | |
6 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | |
7 | * All rights reserved. | |
8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in the | |
16 | * documentation and/or other materials provided with the distribution. | |
17 | * 3. Neither the name of the project nor the names of its contributors | |
18 | * may be used to endorse or promote products derived from this software | |
19 | * without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
31 | * SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #include "config.h" | |
35 | ||
52b7d2ce | 36 | #define COMMON_DIGEST_FOR_OPENSSL 1 |
52b7d2ce A |
37 | |
38 | #include <sys/types.h> | |
39 | #include <sys/param.h> | |
40 | ||
41 | #include <stdlib.h> | |
42 | #include <stdio.h> | |
43 | #include <limits.h> | |
44 | #include <string.h> | |
45 | ||
e8d9021d | 46 | #ifdef HAVE_OPENSSL |
52b7d2ce A |
47 | /* get openssl/ssleay version number */ |
48 | #include <openssl/opensslv.h> | |
49 | ||
50 | #if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090602fL) | |
51 | #error OpenSSL version 0.9.6 or later required. | |
52 | #endif | |
52b7d2ce A |
53 | #include <openssl/pem.h> |
54 | #include <openssl/evp.h> | |
55 | #include <openssl/x509.h> | |
56 | #include <openssl/x509v3.h> | |
57 | #include <openssl/x509_vfy.h> | |
58 | #include <openssl/bn.h> | |
59 | #include <openssl/dh.h> | |
52b7d2ce A |
60 | #include <openssl/des.h> |
61 | #include <openssl/crypto.h> | |
62 | #ifdef HAVE_OPENSSL_ENGINE_H | |
63 | #include <openssl/engine.h> | |
64 | #endif | |
52b7d2ce | 65 | #include <openssl/err.h> |
e8d9021d A |
66 | #else /* HAVE_OPENSSL */ |
67 | #include <Security/SecDH.h> | |
68 | #include <Security/SecRandom.h> | |
69 | #endif /* HAVE_OPENSSL */ | |
70 | ||
71 | #include <CommonCrypto/CommonDigest.h> | |
72 | #include <CommonCrypto/CommonHMAC.h> | |
73 | #include <CommonCrypto/CommonCryptor.h> | |
52b7d2ce | 74 | |
e8d9021d | 75 | #ifdef HAVE_OPENSSL |
52b7d2ce A |
76 | /* 0.9.7 stuff? */ |
77 | #if OPENSSL_VERSION_NUMBER < 0x0090700fL | |
78 | typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; | |
79 | #else | |
80 | #define USE_NEW_DES_API | |
81 | #endif | |
82 | ||
65c25746 | 83 | #define OpenSSL_BUG() do { plog(ASL_LEVEL_ERR, "OpenSSL function failed\n"); } while(0) |
e8d9021d | 84 | #endif |
52b7d2ce | 85 | |
e8d9021d | 86 | #include "crypto_openssl.h" |
52b7d2ce A |
87 | #include "var.h" |
88 | #include "misc.h" | |
89 | #include "vmbuf.h" | |
90 | #include "plog.h" | |
52b7d2ce A |
91 | #include "debug.h" |
92 | #include "gcmalloc.h" | |
93 | ||
94 | ||
95 | /* | |
96 | * I hate to cast every parameter to des_xx into void *, but it is | |
97 | * necessary for SSLeay/OpenSSL portability. It sucks. | |
98 | */ | |
99 | ||
e8d9021d | 100 | #ifdef HAVE_OPENSSL |
65c25746 | 101 | static X509 *mem2x509(vchar_t *); |
52b7d2ce | 102 | #endif |
65c25746 | 103 | static caddr_t eay_hmac_init (vchar_t *, CCHmacAlgorithm); |
e8d9021d | 104 | |
52b7d2ce | 105 | |
e8d9021d | 106 | #ifdef HAVE_OPENSSL |
52b7d2ce A |
107 | |
108 | /* | |
109 | * The following are derived from code in crypto/x509/x509_cmp.c | |
110 | * in OpenSSL0.9.7c: | |
111 | * X509_NAME_wildcmp() adds wildcard matching to the original | |
112 | * X509_NAME_cmp(), nocase_cmp() and nocase_spacenorm_cmp() are as is. | |
113 | */ | |
114 | #include <ctype.h> | |
115 | /* Case insensitive string comparision */ | |
116 | static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b) | |
117 | { | |
118 | int i; | |
119 | ||
120 | if (a->length != b->length) | |
121 | return (a->length - b->length); | |
122 | ||
123 | for (i=0; i<a->length; i++) | |
124 | { | |
125 | int ca, cb; | |
126 | ||
127 | ca = tolower(a->data[i]); | |
128 | cb = tolower(b->data[i]); | |
129 | ||
130 | if (ca != cb) | |
131 | return(ca-cb); | |
132 | } | |
133 | return 0; | |
134 | } | |
135 | ||
136 | /* Case insensitive string comparision with space normalization | |
137 | * Space normalization - ignore leading, trailing spaces, | |
138 | * multiple spaces between characters are replaced by single space | |
139 | */ | |
140 | static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b) | |
141 | { | |
142 | unsigned char *pa = NULL, *pb = NULL; | |
143 | int la, lb; | |
144 | ||
145 | la = a->length; | |
146 | lb = b->length; | |
147 | pa = a->data; | |
148 | pb = b->data; | |
149 | ||
150 | /* skip leading spaces */ | |
151 | while (la > 0 && isspace(*pa)) | |
152 | { | |
153 | la--; | |
154 | pa++; | |
155 | } | |
156 | while (lb > 0 && isspace(*pb)) | |
157 | { | |
158 | lb--; | |
159 | pb++; | |
160 | } | |
161 | ||
162 | /* skip trailing spaces */ | |
163 | while (la > 0 && isspace(pa[la-1])) | |
164 | la--; | |
165 | while (lb > 0 && isspace(pb[lb-1])) | |
166 | lb--; | |
167 | ||
168 | /* compare strings with space normalization */ | |
169 | while (la > 0 && lb > 0) | |
170 | { | |
171 | int ca, cb; | |
172 | ||
173 | /* compare character */ | |
174 | ca = tolower(*pa); | |
175 | cb = tolower(*pb); | |
176 | if (ca != cb) | |
177 | return (ca - cb); | |
178 | ||
179 | pa++; pb++; | |
180 | la--; lb--; | |
181 | ||
182 | if (la <= 0 || lb <= 0) | |
183 | break; | |
184 | ||
185 | /* is white space next character ? */ | |
186 | if (isspace(*pa) && isspace(*pb)) | |
187 | { | |
188 | /* skip remaining white spaces */ | |
189 | while (la > 0 && isspace(*pa)) | |
190 | { | |
191 | la--; | |
192 | pa++; | |
193 | } | |
194 | while (lb > 0 && isspace(*pb)) | |
195 | { | |
196 | lb--; | |
197 | pb++; | |
198 | } | |
199 | } | |
200 | } | |
201 | if (la > 0 || lb > 0) | |
202 | return la - lb; | |
203 | ||
204 | return 0; | |
205 | } | |
206 | ||
207 | static int X509_NAME_wildcmp(const X509_NAME *a, const X509_NAME *b) | |
208 | { | |
209 | int i,j; | |
210 | X509_NAME_ENTRY *na,*nb; | |
211 | ||
212 | if (sk_X509_NAME_ENTRY_num(a->entries) | |
213 | != sk_X509_NAME_ENTRY_num(b->entries)) | |
214 | return sk_X509_NAME_ENTRY_num(a->entries) | |
215 | -sk_X509_NAME_ENTRY_num(b->entries); | |
216 | for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) | |
217 | { | |
218 | na=sk_X509_NAME_ENTRY_value(a->entries,i); | |
219 | nb=sk_X509_NAME_ENTRY_value(b->entries,i); | |
220 | j=OBJ_cmp(na->object,nb->object); | |
221 | if (j) return(j); | |
222 | if ((na->value->length == 1 && na->value->data[0] == '*') | |
223 | || (nb->value->length == 1 && nb->value->data[0] == '*')) | |
224 | continue; | |
225 | j=na->value->type-nb->value->type; | |
226 | if (j) return(j); | |
227 | if (na->value->type == V_ASN1_PRINTABLESTRING) | |
228 | j=nocase_spacenorm_cmp(na->value, nb->value); | |
229 | else if (na->value->type == V_ASN1_IA5STRING | |
230 | && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress) | |
231 | j=nocase_cmp(na->value, nb->value); | |
232 | else | |
233 | { | |
234 | j=na->value->length-nb->value->length; | |
235 | if (j) return(j); | |
236 | j=memcmp(na->value->data,nb->value->data, | |
237 | na->value->length); | |
238 | } | |
239 | if (j) return(j); | |
240 | j=na->set-nb->set; | |
241 | if (j) return(j); | |
242 | } | |
243 | ||
244 | return(0); | |
245 | } | |
246 | ||
247 | /* | |
248 | * compare two subjectNames. | |
249 | * OUT: 0: equal | |
250 | * positive: | |
251 | * -1: other error. | |
252 | */ | |
253 | int | |
254 | eay_cmp_asn1dn(n1, n2) | |
255 | vchar_t *n1, *n2; | |
256 | { | |
257 | X509_NAME *a = NULL, *b = NULL; | |
258 | caddr_t p; | |
259 | int i = -1; | |
260 | ||
261 | p = n1->v; | |
262 | if (!d2i_X509_NAME(&a, (void *)&p, n1->l)) | |
263 | goto end; | |
264 | p = n2->v; | |
265 | if (!d2i_X509_NAME(&b, (void *)&p, n2->l)) | |
266 | goto end; | |
267 | ||
268 | i = X509_NAME_wildcmp(a, b); | |
269 | ||
270 | end: | |
271 | if (a) | |
272 | X509_NAME_free(a); | |
273 | if (b) | |
274 | X509_NAME_free(b); | |
275 | return i; | |
276 | } | |
277 | ||
52b7d2ce A |
278 | /* |
279 | * Get the common name from a cert | |
280 | */ | |
281 | #define EAY_MAX_CN_LEN 256 | |
282 | vchar_t * | |
283 | eay_get_x509_common_name(cert) | |
284 | vchar_t *cert; | |
285 | { | |
286 | X509 *x509 = NULL; | |
287 | X509_NAME *name; | |
288 | vchar_t *commonName = NULL; | |
289 | ||
290 | commonName = vmalloc(EAY_MAX_CN_LEN); | |
291 | if (commonName == NULL) { | |
65c25746 | 292 | plog(ASL_LEVEL_ERR, "no memory\n"); |
52b7d2ce A |
293 | return NULL; |
294 | } | |
295 | ||
296 | x509 = mem2x509(cert); | |
297 | if (x509 == NULL) { | |
298 | vfree(commonName); | |
299 | return NULL; | |
300 | } | |
301 | ||
302 | name = X509_get_subject_name(x509); | |
303 | X509_NAME_get_text_by_NID(name, NID_commonName, commonName->v, EAY_MAX_CN_LEN); | |
304 | ||
305 | commonName->l = strlen(commonName->v); | |
306 | ||
307 | if (x509) | |
308 | X509_free(x509); | |
309 | return commonName; | |
310 | } | |
311 | ||
312 | /* | |
313 | * get the subjectAltName from X509 certificate. | |
314 | * the name must be terminated by '\0'. | |
315 | */ | |
316 | int | |
317 | eay_get_x509subjectaltname(cert, altname, type, pos, len) | |
318 | vchar_t *cert; | |
319 | char **altname; | |
320 | int *type; | |
321 | int pos; | |
322 | int *len; | |
323 | { | |
324 | X509 *x509 = NULL; | |
325 | int i; | |
d1e348cf | 326 | GENERAL_NAMES *gens = NULL; |
52b7d2ce A |
327 | GENERAL_NAME *gen; |
328 | int error = -1; | |
329 | ||
330 | *altname = NULL; | |
331 | *type = GENT_OTHERNAME; | |
332 | ||
333 | x509 = mem2x509(cert); | |
334 | if (x509 == NULL) | |
335 | goto end; | |
336 | ||
337 | gens = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL); | |
338 | if (gens == NULL) | |
339 | goto end; | |
340 | ||
341 | for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { | |
342 | if (i + 1 != pos) | |
343 | continue; | |
344 | break; | |
345 | } | |
346 | ||
347 | /* there is no data at "pos" */ | |
348 | if (i == sk_GENERAL_NAME_num(gens)) | |
349 | goto end; | |
350 | ||
351 | gen = sk_GENERAL_NAME_value(gens, i); | |
352 | ||
353 | /* make sure the data is terminated by '\0'. */ | |
354 | if (gen->d.ia5->data[gen->d.ia5->length] != '\0') { | |
65c25746 | 355 | plog(ASL_LEVEL_ERR, |
52b7d2ce A |
356 | "data is not terminated by 0."); |
357 | hexdump(gen->d.ia5->data, gen->d.ia5->length + 1); | |
358 | goto end; | |
359 | } | |
360 | ||
361 | /* read DNSName / Email */ | |
362 | if (gen->type == GEN_DNS || | |
363 | gen->type == GEN_EMAIL || | |
364 | gen->type == GEN_URI) { | |
365 | ||
366 | *len = gen->d.ia5->length + 1; | |
367 | *altname = racoon_malloc(*len); | |
368 | if (!*altname) | |
369 | goto end; | |
370 | ||
371 | strlcpy(*altname, (const char *)gen->d.ia5->data, *len); | |
372 | *type = gen->type; | |
373 | ||
374 | error = 0; | |
375 | } else if (gen->type == GEN_IPADD) { | |
376 | ||
377 | *len = gen->d.ia5->length + 1; | |
378 | *altname = racoon_malloc(*len); | |
379 | if (!*altname) | |
380 | goto end; | |
381 | ||
382 | memcpy(*altname, (const char *)gen->d.ia5->data, *len); | |
383 | *type = gen->type; | |
384 | ||
385 | error = 0; | |
386 | } | |
387 | ||
388 | end: | |
389 | if (error) { | |
390 | if (*altname) { | |
391 | racoon_free(*altname); | |
392 | *altname = NULL; | |
393 | } | |
394 | #ifndef EAYDEBUG | |
65c25746 | 395 | plog(ASL_LEVEL_ERR, "%s\n", eay_strerror()); |
52b7d2ce A |
396 | #else |
397 | printf("%s\n", eay_strerror()); | |
398 | #endif | |
399 | } | |
d1e348cf A |
400 | if (gens) |
401 | /* free the whole stack. */ | |
402 | sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); | |
52b7d2ce A |
403 | if (x509) |
404 | X509_free(x509); | |
405 | ||
406 | return error; | |
407 | } | |
408 | ||
52b7d2ce A |
409 | |
410 | /* get X509 structure from buffer. */ | |
411 | static X509 * | |
412 | mem2x509(cert) | |
413 | vchar_t *cert; | |
414 | { | |
415 | X509 *x509; | |
416 | ||
417 | #ifndef EAYDEBUG | |
418 | { | |
419 | u_char *bp; | |
420 | ||
421 | bp = (unsigned char *) cert->v; | |
422 | ||
423 | x509 = d2i_X509(NULL, (void *)&bp, cert->l); | |
424 | } | |
425 | #else | |
426 | { | |
427 | BIO *bio; | |
428 | int len; | |
429 | ||
430 | bio = BIO_new(BIO_s_mem()); | |
431 | if (bio == NULL) | |
432 | return NULL; | |
433 | len = BIO_write(bio, cert->v, cert->l); | |
434 | if (len == -1) | |
435 | return NULL; | |
436 | x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); | |
437 | BIO_free(bio); | |
438 | } | |
439 | #endif | |
440 | return x509; | |
441 | } | |
442 | ||
52b7d2ce A |
443 | /* |
444 | * get error string | |
445 | * MUST load ERR_load_crypto_strings() first. | |
446 | */ | |
447 | char * | |
448 | eay_strerror() | |
449 | { | |
450 | static char ebuf[512]; | |
451 | int len = 0, n; | |
452 | unsigned long l; | |
453 | char buf[200]; | |
454 | const char *file, *data; | |
455 | int line, flags; | |
456 | unsigned long es; | |
457 | ||
458 | es = CRYPTO_thread_id(); | |
459 | ||
460 | while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0){ | |
461 | n = snprintf(ebuf + len, sizeof(ebuf) - len, | |
462 | "%lu:%s:%s:%d:%s ", | |
463 | es, ERR_error_string(l, buf), file, line, | |
464 | (flags & ERR_TXT_STRING) ? data : ""); | |
465 | if (n < 0 || n >= sizeof(ebuf) - len) | |
466 | break; | |
467 | len += n; | |
468 | if (sizeof(ebuf) < len) | |
469 | break; | |
470 | } | |
471 | ||
472 | return ebuf; | |
473 | } | |
474 | ||
e8d9021d | 475 | #endif /* HAVE_OPENSSL */ |
52b7d2ce | 476 | |
d1e348cf A |
477 | vchar_t * |
478 | eay_CCCrypt(CCOperation oper, | |
479 | CCAlgorithm algo, | |
480 | CCOptions opts, | |
481 | vchar_t *data, | |
482 | vchar_t *key, | |
483 | vchar_t *iv) | |
484 | { | |
485 | vchar_t *res; | |
486 | size_t res_len = 0; | |
487 | CCCryptorStatus status; | |
488 | ||
489 | /* allocate buffer for result */ | |
490 | if ((res = vmalloc(data->l)) == NULL) | |
491 | return NULL; | |
492 | ||
493 | status = CCCrypt(oper, | |
494 | algo, | |
495 | opts, | |
496 | key->v, key->l, | |
497 | iv->v, | |
498 | data->v, data->l, | |
499 | res->v, res->l, &res_len); | |
500 | if (status == kCCSuccess) { | |
501 | if (res->l != res_len) { | |
65c25746 | 502 | plog(ASL_LEVEL_ERR, |
d1e348cf A |
503 | "crypt %d %d length mismatch. expected: %zd. got: %zd.\n", |
504 | oper, algo, res->l, res_len); | |
505 | } | |
506 | return res; | |
507 | } else { | |
65c25746 | 508 | plog(ASL_LEVEL_ERR, |
d1e348cf A |
509 | "crypt %d %d error. status %d.\n", |
510 | oper, algo, (int)status); | |
511 | } | |
512 | vfree(res); | |
513 | return NULL; | |
514 | } | |
515 | ||
52b7d2ce A |
516 | /* |
517 | * DES-CBC | |
518 | */ | |
519 | vchar_t * | |
520 | eay_des_encrypt(data, key, iv) | |
521 | vchar_t *data, *key, *iv; | |
522 | { | |
d1e348cf | 523 | return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv)); |
52b7d2ce A |
524 | } |
525 | ||
526 | vchar_t * | |
527 | eay_des_decrypt(data, key, iv) | |
528 | vchar_t *data, *key, *iv; | |
529 | { | |
d1e348cf | 530 | return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmDES, 0 /* CBC */, data, key, iv)); |
52b7d2ce A |
531 | } |
532 | ||
533 | int | |
534 | eay_des_weakkey(key) | |
535 | vchar_t *key; | |
536 | { | |
e8d9021d | 537 | #ifdef HAVE_OPENSSL |
52b7d2ce A |
538 | #ifdef USE_NEW_DES_API |
539 | return DES_is_weak_key((void *)key->v); | |
540 | #else | |
541 | return des_is_weak_key((void *)key->v); | |
542 | #endif | |
e8d9021d A |
543 | #else |
544 | return 0; | |
545 | #endif | |
52b7d2ce A |
546 | } |
547 | ||
548 | int | |
549 | eay_des_keylen(len) | |
550 | int len; | |
551 | { | |
d1e348cf A |
552 | /* CommonCrypto return lengths in bytes, ipsec-tools |
553 | * uses lengths in bits, therefore conversion is required. | |
554 | */ | |
555 | if (len != 0 && len != (kCCKeySizeDES << 3)) | |
556 | return -1; | |
557 | ||
558 | return kCCKeySizeDES << 3; | |
52b7d2ce A |
559 | } |
560 | ||
52b7d2ce A |
561 | /* |
562 | * 3DES-CBC | |
563 | */ | |
564 | vchar_t * | |
565 | eay_3des_encrypt(data, key, iv) | |
566 | vchar_t *data, *key, *iv; | |
567 | { | |
d1e348cf | 568 | return(eay_CCCrypt(kCCEncrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv)); |
52b7d2ce A |
569 | } |
570 | ||
571 | vchar_t * | |
572 | eay_3des_decrypt(data, key, iv) | |
573 | vchar_t *data, *key, *iv; | |
574 | { | |
d1e348cf | 575 | return(eay_CCCrypt(kCCDecrypt, kCCAlgorithm3DES, 0 /* CBC */, data, key, iv)); |
52b7d2ce A |
576 | } |
577 | ||
578 | int | |
579 | eay_3des_weakkey(key) | |
580 | vchar_t *key; | |
581 | { | |
e8d9021d | 582 | return 0; |
52b7d2ce A |
583 | } |
584 | ||
585 | int | |
586 | eay_3des_keylen(len) | |
587 | int len; | |
588 | { | |
d1e348cf A |
589 | /* CommonCrypto return lengths in bytes, ipsec-tools |
590 | * uses lengths in bits, therefore conversion is required. | |
591 | */ | |
592 | if (len != 0 && len != (kCCKeySize3DES << 3)) | |
593 | return -1; | |
594 | ||
595 | return kCCKeySize3DES << 3; | |
52b7d2ce A |
596 | } |
597 | ||
52b7d2ce A |
598 | /* |
599 | * AES(RIJNDAEL)-CBC | |
600 | */ | |
d1e348cf A |
601 | vchar_t * |
602 | eay_aes_encrypt(data, key, iv) | |
603 | vchar_t *data, *key, *iv; | |
604 | { | |
605 | return(eay_CCCrypt(kCCEncrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv)); | |
606 | } | |
607 | ||
608 | vchar_t * | |
609 | eay_aes_decrypt(data, key, iv) | |
610 | vchar_t *data, *key, *iv; | |
611 | { | |
612 | return(eay_CCCrypt(kCCDecrypt, kCCAlgorithmAES128 /* adapts to AES-192, or AES-256 depending on the key size*/, 0 /* CBC */, data, key, iv)); | |
613 | } | |
614 | ||
615 | int | |
616 | eay_aes_keylen(len) | |
617 | int len; | |
618 | { | |
619 | /* CommonCrypto return lengths in bytes, ipsec-tools | |
620 | * uses lengths in bits, therefore conversion is required. | |
621 | */ | |
622 | if (len != 0) { | |
623 | if (len != (kCCKeySizeAES128 << 3) && | |
624 | len != (kCCKeySizeAES192 << 3) && | |
625 | len != (kCCKeySizeAES256 << 3)) | |
626 | return -1; | |
627 | } else { | |
628 | return kCCKeySizeAES128 << 3; | |
629 | } | |
630 | return len; | |
631 | } | |
632 | ||
d1e348cf A |
633 | |
634 | int | |
635 | eay_aes_weakkey(key) | |
636 | vchar_t *key; | |
637 | { | |
638 | return 0; | |
639 | } | |
52b7d2ce A |
640 | |
641 | /* for ipsec part */ | |
642 | int | |
643 | eay_null_hashlen() | |
644 | { | |
645 | return 0; | |
646 | } | |
647 | ||
52b7d2ce A |
648 | int |
649 | eay_null_keylen(len) | |
650 | int len; | |
651 | { | |
652 | return 0; | |
653 | } | |
654 | ||
655 | /* | |
656 | * HMAC functions | |
657 | */ | |
52b7d2ce A |
658 | static caddr_t |
659 | eay_hmac_init(key, algorithm) | |
660 | vchar_t *key; | |
661 | CCHmacAlgorithm algorithm; | |
662 | { | |
663 | CCHmacContext *c = racoon_malloc(sizeof(*c)); | |
664 | ||
665 | CCHmacInit(c, algorithm, key->v, key->l); | |
666 | ||
667 | return (caddr_t)c; | |
668 | } | |
52b7d2ce A |
669 | |
670 | #ifdef WITH_SHA2 | |
671 | /* | |
672 | * HMAC SHA2-512 | |
673 | */ | |
674 | vchar_t * | |
675 | eay_hmacsha2_512_one(key, data) | |
676 | vchar_t *key, *data; | |
677 | { | |
678 | vchar_t *res; | |
679 | caddr_t ctx; | |
680 | ||
681 | ctx = eay_hmacsha2_512_init(key); | |
682 | eay_hmacsha2_512_update(ctx, data); | |
683 | res = eay_hmacsha2_512_final(ctx); | |
684 | ||
685 | return(res); | |
686 | } | |
687 | ||
688 | caddr_t | |
689 | eay_hmacsha2_512_init(key) | |
690 | vchar_t *key; | |
691 | { | |
52b7d2ce | 692 | return eay_hmac_init(key, kCCHmacAlgSHA512); |
52b7d2ce A |
693 | } |
694 | ||
695 | void | |
696 | eay_hmacsha2_512_update(c, data) | |
697 | caddr_t c; | |
698 | vchar_t *data; | |
699 | { | |
85f41bec | 700 | CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l); |
52b7d2ce A |
701 | } |
702 | ||
52b7d2ce A |
703 | vchar_t * |
704 | eay_hmacsha2_512_final(c) | |
705 | caddr_t c; | |
706 | { | |
707 | vchar_t *res; | |
708 | ||
709 | if ((res = vmalloc(CC_SHA512_DIGEST_LENGTH)) == 0) | |
710 | return NULL; | |
711 | ||
85f41bec | 712 | CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v); |
52b7d2ce A |
713 | res->l = CC_SHA512_DIGEST_LENGTH; |
714 | ||
715 | (void)racoon_free(c); | |
716 | return(res); | |
717 | } | |
52b7d2ce A |
718 | |
719 | /* | |
720 | * HMAC SHA2-384 | |
721 | */ | |
722 | vchar_t * | |
723 | eay_hmacsha2_384_one(key, data) | |
724 | vchar_t *key, *data; | |
725 | { | |
726 | vchar_t *res; | |
727 | caddr_t ctx; | |
728 | ||
729 | ctx = eay_hmacsha2_384_init(key); | |
730 | eay_hmacsha2_384_update(ctx, data); | |
731 | res = eay_hmacsha2_384_final(ctx); | |
732 | ||
733 | return(res); | |
734 | } | |
735 | ||
736 | caddr_t | |
737 | eay_hmacsha2_384_init(key) | |
738 | vchar_t *key; | |
739 | { | |
52b7d2ce | 740 | return eay_hmac_init(key, kCCHmacAlgSHA384); |
52b7d2ce A |
741 | } |
742 | ||
743 | void | |
744 | eay_hmacsha2_384_update(c, data) | |
745 | caddr_t c; | |
746 | vchar_t *data; | |
747 | { | |
85f41bec | 748 | CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l); |
52b7d2ce A |
749 | } |
750 | ||
52b7d2ce A |
751 | vchar_t * |
752 | eay_hmacsha2_384_final(c) | |
753 | caddr_t c; | |
754 | { | |
755 | vchar_t *res; | |
756 | ||
757 | if ((res = vmalloc(CC_SHA384_DIGEST_LENGTH)) == 0) | |
758 | return NULL; | |
759 | ||
85f41bec | 760 | CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v); |
52b7d2ce A |
761 | res->l = CC_SHA384_DIGEST_LENGTH; |
762 | ||
763 | (void)racoon_free(c); | |
764 | return(res); | |
765 | } | |
52b7d2ce A |
766 | |
767 | /* | |
768 | * HMAC SHA2-256 | |
769 | */ | |
770 | vchar_t * | |
771 | eay_hmacsha2_256_one(key, data) | |
772 | vchar_t *key, *data; | |
773 | { | |
774 | vchar_t *res; | |
775 | caddr_t ctx; | |
776 | ||
777 | ctx = eay_hmacsha2_256_init(key); | |
778 | eay_hmacsha2_256_update(ctx, data); | |
779 | res = eay_hmacsha2_256_final(ctx); | |
780 | ||
781 | return(res); | |
782 | } | |
783 | ||
784 | caddr_t | |
785 | eay_hmacsha2_256_init(key) | |
786 | vchar_t *key; | |
787 | { | |
52b7d2ce | 788 | return eay_hmac_init(key, kCCHmacAlgSHA256); |
52b7d2ce A |
789 | } |
790 | ||
791 | void | |
792 | eay_hmacsha2_256_update(c, data) | |
793 | caddr_t c; | |
794 | vchar_t *data; | |
795 | { | |
85f41bec | 796 | CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l); |
52b7d2ce A |
797 | } |
798 | ||
52b7d2ce A |
799 | vchar_t * |
800 | eay_hmacsha2_256_final(c) | |
801 | caddr_t c; | |
802 | { | |
803 | vchar_t *res; | |
804 | ||
805 | if ((res = vmalloc(CC_SHA256_DIGEST_LENGTH)) == 0) | |
806 | return NULL; | |
807 | ||
85f41bec | 808 | CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v); |
52b7d2ce A |
809 | res->l = CC_SHA256_DIGEST_LENGTH; |
810 | ||
811 | (void)racoon_free(c); | |
812 | return(res); | |
813 | } | |
52b7d2ce A |
814 | #endif /* WITH_SHA2 */ |
815 | ||
816 | /* | |
817 | * HMAC SHA1 | |
818 | */ | |
819 | vchar_t * | |
820 | eay_hmacsha1_one(key, data) | |
821 | vchar_t *key, *data; | |
822 | { | |
823 | vchar_t *res; | |
824 | caddr_t ctx; | |
825 | ||
826 | ctx = eay_hmacsha1_init(key); | |
827 | eay_hmacsha1_update(ctx, data); | |
828 | res = eay_hmacsha1_final(ctx); | |
829 | ||
830 | return(res); | |
831 | } | |
832 | ||
833 | caddr_t | |
834 | eay_hmacsha1_init(key) | |
835 | vchar_t *key; | |
836 | { | |
52b7d2ce | 837 | return eay_hmac_init(key, kCCHmacAlgSHA1); |
52b7d2ce A |
838 | } |
839 | ||
840 | void | |
841 | eay_hmacsha1_update(c, data) | |
842 | caddr_t c; | |
843 | vchar_t *data; | |
844 | { | |
85f41bec | 845 | CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l); |
52b7d2ce A |
846 | } |
847 | ||
52b7d2ce A |
848 | vchar_t * |
849 | eay_hmacsha1_final(c) | |
850 | caddr_t c; | |
851 | { | |
852 | vchar_t *res; | |
853 | ||
854 | if ((res = vmalloc(CC_SHA1_DIGEST_LENGTH)) == 0) | |
855 | return NULL; | |
856 | ||
85f41bec | 857 | CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v); |
52b7d2ce A |
858 | res->l = CC_SHA1_DIGEST_LENGTH; |
859 | ||
860 | (void)racoon_free(c); | |
861 | return(res); | |
862 | } | |
52b7d2ce A |
863 | |
864 | /* | |
865 | * HMAC MD5 | |
866 | */ | |
867 | vchar_t * | |
868 | eay_hmacmd5_one(key, data) | |
869 | vchar_t *key, *data; | |
870 | { | |
871 | vchar_t *res; | |
872 | caddr_t ctx; | |
873 | ||
874 | ctx = eay_hmacmd5_init(key); | |
875 | eay_hmacmd5_update(ctx, data); | |
876 | res = eay_hmacmd5_final(ctx); | |
877 | ||
878 | return(res); | |
879 | } | |
880 | ||
881 | caddr_t | |
882 | eay_hmacmd5_init(key) | |
883 | vchar_t *key; | |
884 | { | |
52b7d2ce | 885 | return eay_hmac_init(key, kCCHmacAlgMD5); |
52b7d2ce A |
886 | } |
887 | ||
888 | void | |
889 | eay_hmacmd5_update(c, data) | |
890 | caddr_t c; | |
891 | vchar_t *data; | |
892 | { | |
85f41bec | 893 | CCHmacUpdate(ALIGNED_CAST(CCHmacContext *)c, data->v, data->l); |
52b7d2ce A |
894 | } |
895 | ||
52b7d2ce A |
896 | vchar_t * |
897 | eay_hmacmd5_final(c) | |
898 | caddr_t c; | |
899 | { | |
900 | vchar_t *res; | |
901 | ||
902 | if ((res = vmalloc(CC_MD5_DIGEST_LENGTH)) == 0) | |
903 | return NULL; | |
904 | ||
85f41bec | 905 | CCHmacFinal(ALIGNED_CAST(CCHmacContext *)c, res->v); |
52b7d2ce A |
906 | res->l = CC_MD5_DIGEST_LENGTH; |
907 | (void)racoon_free(c); | |
908 | ||
909 | return(res); | |
910 | } | |
52b7d2ce | 911 | |
52b7d2ce | 912 | |
65c25746 | 913 | |
52b7d2ce A |
914 | #ifdef WITH_SHA2 |
915 | /* | |
916 | * SHA2-512 functions | |
917 | */ | |
918 | caddr_t | |
919 | eay_sha2_512_init() | |
920 | { | |
921 | SHA512_CTX *c = racoon_malloc(sizeof(*c)); | |
922 | ||
923 | SHA512_Init(c); | |
924 | ||
925 | return((caddr_t)c); | |
926 | } | |
927 | ||
928 | void | |
929 | eay_sha2_512_update(c, data) | |
930 | caddr_t c; | |
931 | vchar_t *data; | |
932 | { | |
85f41bec | 933 | SHA512_Update(ALIGNED_CAST(SHA512_CTX *)c, (unsigned char *) data->v, data->l); |
52b7d2ce A |
934 | |
935 | return; | |
936 | } | |
937 | ||
938 | vchar_t * | |
939 | eay_sha2_512_final(c) | |
940 | caddr_t c; | |
941 | { | |
942 | vchar_t *res; | |
943 | ||
944 | if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0) | |
945 | return(0); | |
946 | ||
85f41bec | 947 | SHA512_Final((unsigned char *) res->v, ALIGNED_CAST(SHA512_CTX *)c); |
52b7d2ce A |
948 | (void)racoon_free(c); |
949 | ||
950 | return(res); | |
951 | } | |
952 | ||
953 | vchar_t * | |
954 | eay_sha2_512_one(data) | |
955 | vchar_t *data; | |
956 | { | |
957 | caddr_t ctx; | |
958 | vchar_t *res; | |
959 | ||
960 | ctx = eay_sha2_512_init(); | |
961 | eay_sha2_512_update(ctx, data); | |
962 | res = eay_sha2_512_final(ctx); | |
963 | ||
964 | return(res); | |
965 | } | |
966 | ||
967 | int | |
968 | eay_sha2_512_hashlen() | |
969 | { | |
970 | return SHA512_DIGEST_LENGTH << 3; | |
971 | } | |
972 | #endif | |
973 | ||
974 | #ifdef WITH_SHA2 | |
975 | /* | |
976 | * SHA2-384 functions | |
977 | */ | |
978 | ||
52b7d2ce | 979 | typedef SHA512_CTX SHA384_CTX; |
52b7d2ce A |
980 | |
981 | caddr_t | |
982 | eay_sha2_384_init() | |
983 | { | |
984 | SHA384_CTX *c = racoon_malloc(sizeof(*c)); | |
985 | ||
986 | SHA384_Init(c); | |
987 | ||
988 | return((caddr_t)c); | |
989 | } | |
990 | ||
991 | void | |
992 | eay_sha2_384_update(c, data) | |
993 | caddr_t c; | |
994 | vchar_t *data; | |
995 | { | |
85f41bec | 996 | SHA384_Update(ALIGNED_CAST(SHA384_CTX *)c, (unsigned char *) data->v, data->l); |
52b7d2ce A |
997 | |
998 | return; | |
999 | } | |
1000 | ||
1001 | vchar_t * | |
1002 | eay_sha2_384_final(c) | |
1003 | caddr_t c; | |
1004 | { | |
1005 | vchar_t *res; | |
1006 | ||
1007 | if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0) | |
1008 | return(0); | |
1009 | ||
85f41bec | 1010 | SHA384_Final((unsigned char *) res->v, ALIGNED_CAST(SHA384_CTX *)c); |
52b7d2ce A |
1011 | (void)racoon_free(c); |
1012 | ||
1013 | return(res); | |
1014 | } | |
1015 | ||
1016 | vchar_t * | |
1017 | eay_sha2_384_one(data) | |
1018 | vchar_t *data; | |
1019 | { | |
1020 | caddr_t ctx; | |
1021 | vchar_t *res; | |
1022 | ||
1023 | ctx = eay_sha2_384_init(); | |
1024 | eay_sha2_384_update(ctx, data); | |
1025 | res = eay_sha2_384_final(ctx); | |
1026 | ||
1027 | return(res); | |
1028 | } | |
1029 | ||
1030 | int | |
1031 | eay_sha2_384_hashlen() | |
1032 | { | |
1033 | return SHA384_DIGEST_LENGTH << 3; | |
1034 | } | |
1035 | #endif | |
1036 | ||
1037 | #ifdef WITH_SHA2 | |
1038 | /* | |
1039 | * SHA2-256 functions | |
1040 | */ | |
1041 | caddr_t | |
1042 | eay_sha2_256_init() | |
1043 | { | |
1044 | SHA256_CTX *c = racoon_malloc(sizeof(*c)); | |
1045 | ||
1046 | SHA256_Init(c); | |
1047 | ||
1048 | return((caddr_t)c); | |
1049 | } | |
1050 | ||
1051 | void | |
1052 | eay_sha2_256_update(c, data) | |
1053 | caddr_t c; | |
1054 | vchar_t *data; | |
1055 | { | |
85f41bec | 1056 | SHA256_Update(ALIGNED_CAST(SHA256_CTX *)c, (unsigned char *) data->v, data->l); |
52b7d2ce A |
1057 | |
1058 | return; | |
1059 | } | |
1060 | ||
1061 | vchar_t * | |
1062 | eay_sha2_256_final(c) | |
1063 | caddr_t c; | |
1064 | { | |
1065 | vchar_t *res; | |
1066 | ||
1067 | if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0) | |
1068 | return(0); | |
1069 | ||
85f41bec | 1070 | SHA256_Final((unsigned char *) res->v, ALIGNED_CAST(SHA256_CTX *)c); |
52b7d2ce A |
1071 | (void)racoon_free(c); |
1072 | ||
1073 | return(res); | |
1074 | } | |
1075 | ||
1076 | vchar_t * | |
1077 | eay_sha2_256_one(data) | |
1078 | vchar_t *data; | |
1079 | { | |
1080 | caddr_t ctx; | |
1081 | vchar_t *res; | |
1082 | ||
1083 | ctx = eay_sha2_256_init(); | |
1084 | eay_sha2_256_update(ctx, data); | |
1085 | res = eay_sha2_256_final(ctx); | |
1086 | ||
1087 | return(res); | |
1088 | } | |
1089 | ||
1090 | int | |
1091 | eay_sha2_256_hashlen() | |
1092 | { | |
1093 | return SHA256_DIGEST_LENGTH << 3; | |
1094 | } | |
1095 | #endif | |
1096 | ||
1097 | /* | |
1098 | * SHA functions | |
1099 | */ | |
1100 | caddr_t | |
1101 | eay_sha1_init() | |
1102 | { | |
1103 | SHA_CTX *c = racoon_malloc(sizeof(*c)); | |
1104 | ||
1105 | SHA1_Init(c); | |
1106 | ||
1107 | return((caddr_t)c); | |
1108 | } | |
1109 | ||
1110 | void | |
1111 | eay_sha1_update(c, data) | |
1112 | caddr_t c; | |
1113 | vchar_t *data; | |
1114 | { | |
85f41bec | 1115 | SHA1_Update(ALIGNED_CAST(SHA_CTX *)c, data->v, data->l); |
52b7d2ce A |
1116 | |
1117 | return; | |
1118 | } | |
1119 | ||
1120 | vchar_t * | |
1121 | eay_sha1_final(c) | |
1122 | caddr_t c; | |
1123 | { | |
1124 | vchar_t *res; | |
1125 | ||
1126 | if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0) | |
1127 | return(0); | |
1128 | ||
85f41bec | 1129 | SHA1_Final((unsigned char *) res->v, ALIGNED_CAST(SHA_CTX *)c); |
52b7d2ce A |
1130 | (void)racoon_free(c); |
1131 | ||
1132 | return(res); | |
1133 | } | |
1134 | ||
1135 | vchar_t * | |
1136 | eay_sha1_one(data) | |
1137 | vchar_t *data; | |
1138 | { | |
1139 | caddr_t ctx; | |
1140 | vchar_t *res; | |
1141 | ||
1142 | ctx = eay_sha1_init(); | |
1143 | eay_sha1_update(ctx, data); | |
1144 | res = eay_sha1_final(ctx); | |
1145 | ||
1146 | return(res); | |
1147 | } | |
1148 | ||
1149 | int | |
1150 | eay_sha1_hashlen() | |
1151 | { | |
1152 | return SHA_DIGEST_LENGTH << 3; | |
1153 | } | |
1154 | ||
1155 | /* | |
1156 | * MD5 functions | |
1157 | */ | |
1158 | caddr_t | |
1159 | eay_md5_init() | |
1160 | { | |
1161 | MD5_CTX *c = racoon_malloc(sizeof(*c)); | |
1162 | ||
1163 | MD5_Init(c); | |
1164 | ||
1165 | return((caddr_t)c); | |
1166 | } | |
1167 | ||
1168 | void | |
1169 | eay_md5_update(c, data) | |
1170 | caddr_t c; | |
1171 | vchar_t *data; | |
1172 | { | |
85f41bec | 1173 | MD5_Update(ALIGNED_CAST(MD5_CTX *)c, data->v, data->l); |
52b7d2ce A |
1174 | |
1175 | return; | |
1176 | } | |
1177 | ||
1178 | vchar_t * | |
1179 | eay_md5_final(c) | |
1180 | caddr_t c; | |
1181 | { | |
1182 | vchar_t *res; | |
1183 | ||
1184 | if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0) | |
1185 | return(0); | |
1186 | ||
85f41bec | 1187 | MD5_Final((unsigned char *) res->v, ALIGNED_CAST(MD5_CTX *)c); |
52b7d2ce A |
1188 | (void)racoon_free(c); |
1189 | ||
1190 | return(res); | |
1191 | } | |
1192 | ||
1193 | vchar_t * | |
1194 | eay_md5_one(data) | |
1195 | vchar_t *data; | |
1196 | { | |
1197 | caddr_t ctx; | |
1198 | vchar_t *res; | |
1199 | ||
1200 | ctx = eay_md5_init(); | |
1201 | eay_md5_update(ctx, data); | |
1202 | res = eay_md5_final(ctx); | |
1203 | ||
1204 | return(res); | |
1205 | } | |
1206 | ||
1207 | int | |
1208 | eay_md5_hashlen() | |
1209 | { | |
1210 | return MD5_DIGEST_LENGTH << 3; | |
1211 | } | |
1212 | ||
e8d9021d A |
1213 | |
1214 | #ifdef HAVE_OPENSSL | |
52b7d2ce A |
1215 | /* |
1216 | * eay_set_random | |
1217 | * size: number of bytes. | |
1218 | */ | |
1219 | vchar_t * | |
1220 | eay_set_random(size) | |
1221 | u_int32_t size; | |
1222 | { | |
1223 | BIGNUM *r = NULL; | |
1224 | vchar_t *res = 0; | |
1225 | ||
1226 | if ((r = BN_new()) == NULL) | |
1227 | goto end; | |
1228 | BN_rand(r, size * 8, 0, 0); | |
1229 | eay_bn2v(&res, r); | |
1230 | ||
1231 | end: | |
1232 | if (r) | |
1233 | BN_free(r); | |
1234 | return(res); | |
1235 | } | |
e8d9021d A |
1236 | #else |
1237 | vchar_t * | |
1238 | eay_set_random(u_int32_t size) | |
1239 | { | |
1240 | vchar_t *res = vmalloc(size); | |
1241 | ||
1242 | if (res == NULL) | |
1243 | return NULL; | |
1244 | ||
65c25746 | 1245 | if (SecRandomCopyBytes(kSecRandomDefault, size, (uint8_t*)res->v)) { |
e8d9021d A |
1246 | vfree(res); |
1247 | return NULL; | |
1248 | } | |
1249 | ||
1250 | return res; | |
1251 | } | |
1252 | #endif | |
52b7d2ce | 1253 | |
e8d9021d | 1254 | #ifdef HAVE_OPENSSL |
52b7d2ce A |
1255 | /* DH */ |
1256 | int | |
1257 | eay_dh_generate(prime, g, publen, pub, priv) | |
1258 | vchar_t *prime, **pub, **priv; | |
1259 | u_int publen; | |
1260 | u_int32_t g; | |
1261 | { | |
1262 | BIGNUM *p = NULL; | |
1263 | DH *dh = NULL; | |
1264 | int error = -1; | |
1265 | ||
1266 | /* initialize */ | |
1267 | /* pre-process to generate number */ | |
1268 | if (eay_v2bn(&p, prime) < 0) | |
1269 | goto end; | |
1270 | ||
1271 | if ((dh = DH_new()) == NULL) | |
1272 | goto end; | |
1273 | dh->p = p; | |
1274 | p = NULL; /* p is now part of dh structure */ | |
1275 | dh->g = NULL; | |
1276 | if ((dh->g = BN_new()) == NULL) | |
1277 | goto end; | |
1278 | if (!BN_set_word(dh->g, g)) | |
1279 | goto end; | |
1280 | ||
1281 | if (publen != 0) | |
1282 | dh->length = publen; | |
1283 | ||
1284 | /* generate public and private number */ | |
1285 | if (!DH_generate_key(dh)) | |
1286 | goto end; | |
1287 | ||
1288 | /* copy results to buffers */ | |
1289 | if (eay_bn2v(pub, dh->pub_key) < 0) | |
1290 | goto end; | |
1291 | if (eay_bn2v(priv, dh->priv_key) < 0) { | |
1292 | vfree(*pub); | |
1293 | goto end; | |
1294 | } | |
1295 | ||
1296 | error = 0; | |
1297 | ||
1298 | end: | |
1299 | if (dh != NULL) | |
1300 | DH_free(dh); | |
1301 | if (p != 0) | |
1302 | BN_free(p); | |
1303 | return(error); | |
1304 | } | |
1305 | ||
1306 | int | |
1307 | eay_dh_compute(prime, g, pub, priv, pub2, key) | |
1308 | vchar_t *prime, *pub, *priv, *pub2, **key; | |
1309 | u_int32_t g; | |
1310 | { | |
1311 | BIGNUM *dh_pub = NULL; | |
1312 | DH *dh = NULL; | |
1313 | int l; | |
1314 | unsigned char *v = NULL; | |
1315 | int error = -1; | |
1316 | ||
1317 | /* make public number to compute */ | |
1318 | if (eay_v2bn(&dh_pub, pub2) < 0) | |
1319 | goto end; | |
1320 | ||
1321 | /* make DH structure */ | |
1322 | if ((dh = DH_new()) == NULL) | |
1323 | goto end; | |
1324 | if (eay_v2bn(&dh->p, prime) < 0) | |
1325 | goto end; | |
1326 | if (eay_v2bn(&dh->pub_key, pub) < 0) | |
1327 | goto end; | |
1328 | if (eay_v2bn(&dh->priv_key, priv) < 0) | |
1329 | goto end; | |
1330 | dh->length = pub2->l * 8; | |
1331 | ||
1332 | dh->g = NULL; | |
1333 | if ((dh->g = BN_new()) == NULL) | |
1334 | goto end; | |
1335 | if (!BN_set_word(dh->g, g)) | |
1336 | goto end; | |
1337 | ||
1338 | if ((v = racoon_calloc(prime->l, sizeof(u_char))) == NULL) | |
1339 | goto end; | |
1340 | if ((l = DH_compute_key(v, dh_pub, dh)) == -1) | |
1341 | goto end; | |
1342 | memcpy((*key)->v + (prime->l - l), v, l); | |
1343 | ||
1344 | error = 0; | |
1345 | ||
1346 | end: | |
1347 | if (dh_pub != NULL) | |
1348 | BN_free(dh_pub); | |
1349 | if (dh != NULL) | |
1350 | DH_free(dh); | |
1351 | if (v != NULL) | |
1352 | racoon_free(v); | |
1353 | return(error); | |
1354 | } | |
1355 | ||
1356 | /* | |
1357 | * convert vchar_t <-> BIGNUM. | |
1358 | * | |
1359 | * vchar_t: unit is u_char, network endian, most significant byte first. | |
1360 | * BIGNUM: unit is BN_ULONG, each of BN_ULONG is in host endian, | |
1361 | * least significant BN_ULONG must come first. | |
1362 | * | |
1363 | * hex value of "0x3ffe050104" is represented as follows: | |
1364 | * vchar_t: 3f fe 05 01 04 | |
1365 | * BIGNUM (BN_ULONG = u_int8_t): 04 01 05 fe 3f | |
1366 | * BIGNUM (BN_ULONG = u_int16_t): 0x0104 0xfe05 0x003f | |
1367 | * BIGNUM (BN_ULONG = u_int32_t_t): 0xfe050104 0x0000003f | |
1368 | */ | |
1369 | int | |
1370 | eay_v2bn(bn, var) | |
1371 | BIGNUM **bn; | |
1372 | vchar_t *var; | |
1373 | { | |
1374 | if ((*bn = BN_bin2bn((unsigned char *) var->v, var->l, NULL)) == NULL) | |
1375 | return -1; | |
1376 | ||
1377 | return 0; | |
1378 | } | |
1379 | ||
1380 | int | |
1381 | eay_bn2v(var, bn) | |
1382 | vchar_t **var; | |
1383 | BIGNUM *bn; | |
1384 | { | |
1385 | *var = vmalloc(bn->top * BN_BYTES); | |
1386 | if (*var == NULL) | |
1387 | return(-1); | |
1388 | ||
1389 | (*var)->l = BN_bn2bin(bn, (unsigned char *) (*var)->v); | |
1390 | ||
1391 | return 0; | |
1392 | } | |
1393 | ||
1394 | void | |
1395 | eay_init() | |
1396 | { | |
1397 | OpenSSL_add_all_algorithms(); | |
1398 | ERR_load_crypto_strings(); | |
1399 | #ifdef HAVE_OPENSSL_ENGINE_H | |
1400 | ENGINE_load_builtin_engines(); | |
1401 | ENGINE_register_all_complete(); | |
1402 | #endif | |
1403 | } | |
e8d9021d | 1404 | #endif /* HAVE_OPENSSL */ |
52b7d2ce A |
1405 | |
1406 | u_int32_t | |
1407 | eay_random() | |
1408 | { | |
1409 | u_int32_t result; | |
1410 | vchar_t *vrand; | |
1411 | ||
1412 | vrand = eay_set_random(sizeof(result)); | |
1413 | memcpy(&result, vrand->v, sizeof(result)); | |
1414 | vfree(vrand); | |
1415 | ||
1416 | return result; | |
1417 | } | |
1418 | ||
e8d9021d | 1419 | #ifdef HAVE_OPENSSL |
52b7d2ce A |
1420 | const char * |
1421 | eay_version() | |
1422 | { | |
1423 | return SSLeay_version(SSLEAY_VERSION); | |
1424 | } | |
65c25746 | 1425 | #endif |