1 |
|
|
/* $OpenBSD: crypto.c,v 1.22 2017/08/28 16:28:13 otto Exp $ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> |
5 |
|
|
* |
6 |
|
|
* Permission to use, copy, modify, and distribute this software for any |
7 |
|
|
* purpose with or without fee is hereby granted, provided that the above |
8 |
|
|
* copyright notice and this permission notice appear in all copies. |
9 |
|
|
* |
10 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 |
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 |
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 |
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 |
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 |
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 |
|
|
*/ |
18 |
|
|
|
19 |
|
|
#include <sys/param.h> /* roundup */ |
20 |
|
|
#include <sys/queue.h> |
21 |
|
|
#include <sys/socket.h> |
22 |
|
|
#include <sys/uio.h> |
23 |
|
|
|
24 |
|
|
#include <stdio.h> |
25 |
|
|
#include <stdlib.h> |
26 |
|
|
#include <unistd.h> |
27 |
|
|
#include <string.h> |
28 |
|
|
#include <errno.h> |
29 |
|
|
#include <fcntl.h> |
30 |
|
|
#include <event.h> |
31 |
|
|
|
32 |
|
|
#include <openssl/hmac.h> |
33 |
|
|
#include <openssl/evp.h> |
34 |
|
|
#include <openssl/sha.h> |
35 |
|
|
#include <openssl/md5.h> |
36 |
|
|
#include <openssl/x509.h> |
37 |
|
|
#include <openssl/rsa.h> |
38 |
|
|
|
39 |
|
|
#include "iked.h" |
40 |
|
|
#include "ikev2.h" |
41 |
|
|
|
42 |
|
|
/* RFC 7427, A.1 RSA */ |
43 |
|
|
static const uint8_t sha256WithRSA[] = { |
44 |
|
|
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, |
45 |
|
|
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00 |
46 |
|
|
}; |
47 |
|
|
static const uint8_t sha384WithRSA[] = { |
48 |
|
|
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, |
49 |
|
|
0xf7, 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00 |
50 |
|
|
}; |
51 |
|
|
static const uint8_t sha512WithRSA[] = { |
52 |
|
|
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, |
53 |
|
|
0xf7, 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00 |
54 |
|
|
}; |
55 |
|
|
/* RFC 7427, A.3 ECDSA */ |
56 |
|
|
static const uint8_t ecdsa_sha256[] = { |
57 |
|
|
0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, |
58 |
|
|
0x3d, 0x04, 0x03, 0x02 |
59 |
|
|
}; |
60 |
|
|
static const uint8_t ecdsa_sha384[] = { |
61 |
|
|
0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, |
62 |
|
|
0x3d, 0x04, 0x03, 0x03 |
63 |
|
|
}; |
64 |
|
|
static const uint8_t ecdsa_sha512[] = { |
65 |
|
|
0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, |
66 |
|
|
0x3d, 0x04, 0x03, 0x04 |
67 |
|
|
}; |
68 |
|
|
|
69 |
|
|
static const struct { |
70 |
|
|
int sc_keytype; |
71 |
|
|
const EVP_MD *(*sc_md)(void); |
72 |
|
|
uint8_t sc_len; |
73 |
|
|
const uint8_t *sc_oid; |
74 |
|
|
} schemes[] = { |
75 |
|
|
{ EVP_PKEY_RSA, EVP_sha256, sizeof(sha256WithRSA), sha256WithRSA }, |
76 |
|
|
{ EVP_PKEY_RSA, EVP_sha384, sizeof(sha384WithRSA), sha384WithRSA }, |
77 |
|
|
{ EVP_PKEY_RSA, EVP_sha512, sizeof(sha512WithRSA), sha512WithRSA }, |
78 |
|
|
{ EVP_PKEY_EC, EVP_sha256, sizeof(ecdsa_sha256), ecdsa_sha256 }, |
79 |
|
|
{ EVP_PKEY_EC, EVP_sha384, sizeof(ecdsa_sha384), ecdsa_sha384 }, |
80 |
|
|
{ EVP_PKEY_EC, EVP_sha512, sizeof(ecdsa_sha512), ecdsa_sha512 }, |
81 |
|
|
}; |
82 |
|
|
|
83 |
|
|
int _dsa_verify_init(struct iked_dsa *, const uint8_t *, size_t); |
84 |
|
|
int _dsa_verify_prepare(struct iked_dsa *, uint8_t **, size_t *, |
85 |
|
|
uint8_t **); |
86 |
|
|
int _dsa_sign_encode(struct iked_dsa *, uint8_t *, size_t *); |
87 |
|
|
int _dsa_sign_ecdsa(struct iked_dsa *, uint8_t *, size_t); |
88 |
|
|
|
89 |
|
|
struct iked_hash * |
90 |
|
|
hash_new(uint8_t type, uint16_t id) |
91 |
|
|
{ |
92 |
|
|
struct iked_hash *hash; |
93 |
|
|
const EVP_MD *md = NULL; |
94 |
|
|
HMAC_CTX *ctx = NULL; |
95 |
|
|
int length = 0, fixedkey = 0, trunc = 0; |
96 |
|
|
|
97 |
|
|
switch (type) { |
98 |
|
|
case IKEV2_XFORMTYPE_PRF: |
99 |
|
|
switch (id) { |
100 |
|
|
case IKEV2_XFORMPRF_HMAC_MD5: |
101 |
|
|
md = EVP_md5(); |
102 |
|
|
length = MD5_DIGEST_LENGTH; |
103 |
|
|
break; |
104 |
|
|
case IKEV2_XFORMPRF_HMAC_SHA1: |
105 |
|
|
md = EVP_sha1(); |
106 |
|
|
length = SHA_DIGEST_LENGTH; |
107 |
|
|
break; |
108 |
|
|
case IKEV2_XFORMPRF_HMAC_SHA2_256: |
109 |
|
|
md = EVP_sha256(); |
110 |
|
|
length = SHA256_DIGEST_LENGTH; |
111 |
|
|
break; |
112 |
|
|
case IKEV2_XFORMPRF_HMAC_SHA2_384: |
113 |
|
|
md = EVP_sha384(); |
114 |
|
|
length = SHA384_DIGEST_LENGTH; |
115 |
|
|
break; |
116 |
|
|
case IKEV2_XFORMPRF_HMAC_SHA2_512: |
117 |
|
|
md = EVP_sha512(); |
118 |
|
|
length = SHA512_DIGEST_LENGTH; |
119 |
|
|
break; |
120 |
|
|
case IKEV2_XFORMPRF_AES128_XCBC: |
121 |
|
|
fixedkey = 128 / 8; |
122 |
|
|
length = fixedkey; |
123 |
|
|
/* FALLTHROUGH */ |
124 |
|
|
case IKEV2_XFORMPRF_HMAC_TIGER: |
125 |
|
|
case IKEV2_XFORMPRF_AES128_CMAC: |
126 |
|
|
default: |
127 |
|
|
log_debug("%s: prf %s not supported", __func__, |
128 |
|
|
print_map(id, ikev2_xformprf_map)); |
129 |
|
|
break; |
130 |
|
|
} |
131 |
|
|
break; |
132 |
|
|
case IKEV2_XFORMTYPE_INTEGR: |
133 |
|
|
switch (id) { |
134 |
|
|
case IKEV2_XFORMAUTH_HMAC_MD5_96: |
135 |
|
|
md = EVP_md5(); |
136 |
|
|
length = MD5_DIGEST_LENGTH; |
137 |
|
|
trunc = 12; |
138 |
|
|
break; |
139 |
|
|
case IKEV2_XFORMAUTH_HMAC_SHA1_96: |
140 |
|
|
md = EVP_sha1(); |
141 |
|
|
length = SHA_DIGEST_LENGTH; |
142 |
|
|
trunc = 12; |
143 |
|
|
break; |
144 |
|
|
case IKEV2_XFORMAUTH_HMAC_SHA2_256_128: |
145 |
|
|
md = EVP_sha256(); |
146 |
|
|
length = SHA256_DIGEST_LENGTH; |
147 |
|
|
trunc = 16; |
148 |
|
|
break; |
149 |
|
|
case IKEV2_XFORMAUTH_HMAC_SHA2_384_192: |
150 |
|
|
md = EVP_sha384(); |
151 |
|
|
length = SHA384_DIGEST_LENGTH; |
152 |
|
|
trunc = 24; |
153 |
|
|
break; |
154 |
|
|
case IKEV2_XFORMAUTH_HMAC_SHA2_512_256: |
155 |
|
|
md = EVP_sha512(); |
156 |
|
|
length = SHA512_DIGEST_LENGTH; |
157 |
|
|
trunc = 32; |
158 |
|
|
break; |
159 |
|
|
case IKEV2_XFORMAUTH_NONE: |
160 |
|
|
case IKEV2_XFORMAUTH_DES_MAC: |
161 |
|
|
case IKEV2_XFORMAUTH_KPDK_MD5: |
162 |
|
|
case IKEV2_XFORMAUTH_AES_XCBC_96: |
163 |
|
|
case IKEV2_XFORMAUTH_HMAC_MD5_128: |
164 |
|
|
case IKEV2_XFORMAUTH_HMAC_SHA1_160: |
165 |
|
|
case IKEV2_XFORMAUTH_AES_CMAC_96: |
166 |
|
|
case IKEV2_XFORMAUTH_AES_128_GMAC: |
167 |
|
|
case IKEV2_XFORMAUTH_AES_192_GMAC: |
168 |
|
|
case IKEV2_XFORMAUTH_AES_256_GMAC: |
169 |
|
|
default: |
170 |
|
|
log_debug("%s: auth %s not supported", __func__, |
171 |
|
|
print_map(id, ikev2_xformauth_map)); |
172 |
|
|
break; |
173 |
|
|
} |
174 |
|
|
break; |
175 |
|
|
default: |
176 |
|
|
log_debug("%s: hash type %s not supported", __func__, |
177 |
|
|
print_map(id, ikev2_xformtype_map)); |
178 |
|
|
break; |
179 |
|
|
} |
180 |
|
|
if (md == NULL) |
181 |
|
|
return (NULL); |
182 |
|
|
|
183 |
|
|
if ((hash = calloc(1, sizeof(*hash))) == NULL) { |
184 |
|
|
log_debug("%s: alloc hash", __func__); |
185 |
|
|
return (NULL); |
186 |
|
|
} |
187 |
|
|
|
188 |
|
|
hash->hash_type = type; |
189 |
|
|
hash->hash_id = id; |
190 |
|
|
hash->hash_priv = md; |
191 |
|
|
hash->hash_ctx = NULL; |
192 |
|
|
hash->hash_trunc = trunc; |
193 |
|
|
hash->hash_length = length; |
194 |
|
|
hash->hash_fixedkey = fixedkey; |
195 |
|
|
|
196 |
|
|
if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { |
197 |
|
|
log_debug("%s: alloc hash ctx", __func__); |
198 |
|
|
hash_free(hash); |
199 |
|
|
return (NULL); |
200 |
|
|
} |
201 |
|
|
|
202 |
|
|
HMAC_CTX_init(ctx); |
203 |
|
|
hash->hash_ctx = ctx; |
204 |
|
|
|
205 |
|
|
return (hash); |
206 |
|
|
} |
207 |
|
|
|
208 |
|
|
struct ibuf * |
209 |
|
|
hash_setkey(struct iked_hash *hash, void *key, size_t keylen) |
210 |
|
|
{ |
211 |
|
|
ibuf_release(hash->hash_key); |
212 |
|
|
if ((hash->hash_key = ibuf_new(key, keylen)) == NULL) { |
213 |
|
|
log_debug("%s: alloc hash key", __func__); |
214 |
|
|
return (NULL); |
215 |
|
|
} |
216 |
|
|
return (hash->hash_key); |
217 |
|
|
} |
218 |
|
|
|
219 |
|
|
void |
220 |
|
|
hash_free(struct iked_hash *hash) |
221 |
|
|
{ |
222 |
|
|
if (hash == NULL) |
223 |
|
|
return; |
224 |
|
|
if (hash->hash_ctx != NULL) { |
225 |
|
|
HMAC_CTX_cleanup(hash->hash_ctx); |
226 |
|
|
free(hash->hash_ctx); |
227 |
|
|
} |
228 |
|
|
ibuf_release(hash->hash_key); |
229 |
|
|
free(hash); |
230 |
|
|
} |
231 |
|
|
|
232 |
|
|
void |
233 |
|
|
hash_init(struct iked_hash *hash) |
234 |
|
|
{ |
235 |
|
|
HMAC_Init_ex(hash->hash_ctx, hash->hash_key->buf, |
236 |
|
|
ibuf_length(hash->hash_key), hash->hash_priv, NULL); |
237 |
|
|
} |
238 |
|
|
|
239 |
|
|
void |
240 |
|
|
hash_update(struct iked_hash *hash, void *buf, size_t len) |
241 |
|
|
{ |
242 |
|
|
HMAC_Update(hash->hash_ctx, buf, len); |
243 |
|
|
} |
244 |
|
|
|
245 |
|
|
void |
246 |
|
|
hash_final(struct iked_hash *hash, void *buf, size_t *len) |
247 |
|
|
{ |
248 |
|
|
unsigned int length = 0; |
249 |
|
|
|
250 |
|
|
HMAC_Final(hash->hash_ctx, buf, &length); |
251 |
|
|
*len = (size_t)length; |
252 |
|
|
|
253 |
|
|
/* Truncate the result if required by the alg */ |
254 |
|
|
if (hash->hash_trunc && *len > hash->hash_trunc) |
255 |
|
|
*len = hash->hash_trunc; |
256 |
|
|
} |
257 |
|
|
|
258 |
|
|
size_t |
259 |
|
|
hash_length(struct iked_hash *hash) |
260 |
|
|
{ |
261 |
|
|
if (hash->hash_trunc) |
262 |
|
|
return (hash->hash_trunc); |
263 |
|
|
return (hash->hash_length); |
264 |
|
|
} |
265 |
|
|
|
266 |
|
|
size_t |
267 |
|
|
hash_keylength(struct iked_hash *hash) |
268 |
|
|
{ |
269 |
|
|
return (hash->hash_length); |
270 |
|
|
} |
271 |
|
|
|
272 |
|
|
struct iked_cipher * |
273 |
|
|
cipher_new(uint8_t type, uint16_t id, uint16_t id_length) |
274 |
|
|
{ |
275 |
|
|
struct iked_cipher *encr; |
276 |
|
|
const EVP_CIPHER *cipher = NULL; |
277 |
|
|
EVP_CIPHER_CTX *ctx = NULL; |
278 |
|
|
int length = 0, fixedkey = 0, ivlength = 0; |
279 |
|
|
|
280 |
|
|
switch (type) { |
281 |
|
|
case IKEV2_XFORMTYPE_ENCR: |
282 |
|
|
switch (id) { |
283 |
|
|
case IKEV2_XFORMENCR_3DES: |
284 |
|
|
cipher = EVP_des_ede3_cbc(); |
285 |
|
|
length = EVP_CIPHER_block_size(cipher); |
286 |
|
|
fixedkey = EVP_CIPHER_key_length(cipher); |
287 |
|
|
ivlength = EVP_CIPHER_iv_length(cipher); |
288 |
|
|
break; |
289 |
|
|
case IKEV2_XFORMENCR_AES_CBC: |
290 |
|
|
switch (id_length) { |
291 |
|
|
case 128: |
292 |
|
|
cipher = EVP_aes_128_cbc(); |
293 |
|
|
break; |
294 |
|
|
case 192: |
295 |
|
|
cipher = EVP_aes_192_cbc(); |
296 |
|
|
break; |
297 |
|
|
case 256: |
298 |
|
|
cipher = EVP_aes_256_cbc(); |
299 |
|
|
break; |
300 |
|
|
default: |
301 |
|
|
log_debug("%s: invalid key length %d" |
302 |
|
|
" for cipher %s", __func__, id_length, |
303 |
|
|
print_map(id, ikev2_xformencr_map)); |
304 |
|
|
break; |
305 |
|
|
} |
306 |
|
|
if (cipher == NULL) |
307 |
|
|
break; |
308 |
|
|
length = EVP_CIPHER_block_size(cipher); |
309 |
|
|
ivlength = EVP_CIPHER_iv_length(cipher); |
310 |
|
|
fixedkey = EVP_CIPHER_key_length(cipher); |
311 |
|
|
break; |
312 |
|
|
case IKEV2_XFORMENCR_DES_IV64: |
313 |
|
|
case IKEV2_XFORMENCR_DES: |
314 |
|
|
case IKEV2_XFORMENCR_RC5: |
315 |
|
|
case IKEV2_XFORMENCR_IDEA: |
316 |
|
|
case IKEV2_XFORMENCR_CAST: |
317 |
|
|
case IKEV2_XFORMENCR_BLOWFISH: |
318 |
|
|
case IKEV2_XFORMENCR_3IDEA: |
319 |
|
|
case IKEV2_XFORMENCR_DES_IV32: |
320 |
|
|
case IKEV2_XFORMENCR_NULL: |
321 |
|
|
case IKEV2_XFORMENCR_AES_CTR: |
322 |
|
|
/* FALLTHROUGH */ |
323 |
|
|
default: |
324 |
|
|
log_debug("%s: cipher %s not supported", __func__, |
325 |
|
|
print_map(id, ikev2_xformencr_map)); |
326 |
|
|
cipher = NULL; |
327 |
|
|
break; |
328 |
|
|
} |
329 |
|
|
break; |
330 |
|
|
default: |
331 |
|
|
log_debug("%s: cipher type %s not supported", __func__, |
332 |
|
|
print_map(id, ikev2_xformtype_map)); |
333 |
|
|
break; |
334 |
|
|
} |
335 |
|
|
if (cipher == NULL) |
336 |
|
|
return (NULL); |
337 |
|
|
|
338 |
|
|
if ((encr = calloc(1, sizeof(*encr))) == NULL) { |
339 |
|
|
log_debug("%s: alloc cipher", __func__); |
340 |
|
|
return (NULL); |
341 |
|
|
} |
342 |
|
|
|
343 |
|
|
encr->encr_id = id; |
344 |
|
|
encr->encr_priv = cipher; |
345 |
|
|
encr->encr_ctx = NULL; |
346 |
|
|
encr->encr_length = length; |
347 |
|
|
encr->encr_fixedkey = fixedkey; |
348 |
|
|
encr->encr_ivlength = ivlength ? ivlength : length; |
349 |
|
|
|
350 |
|
|
if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { |
351 |
|
|
log_debug("%s: alloc cipher ctx", __func__); |
352 |
|
|
cipher_free(encr); |
353 |
|
|
return (NULL); |
354 |
|
|
} |
355 |
|
|
|
356 |
|
|
EVP_CIPHER_CTX_init(ctx); |
357 |
|
|
encr->encr_ctx = ctx; |
358 |
|
|
|
359 |
|
|
return (encr); |
360 |
|
|
} |
361 |
|
|
|
362 |
|
|
struct ibuf * |
363 |
|
|
cipher_setkey(struct iked_cipher *encr, void *key, size_t keylen) |
364 |
|
|
{ |
365 |
|
|
ibuf_release(encr->encr_key); |
366 |
|
|
if ((encr->encr_key = ibuf_new(key, keylen)) == NULL) { |
367 |
|
|
log_debug("%s: alloc cipher key", __func__); |
368 |
|
|
return (NULL); |
369 |
|
|
} |
370 |
|
|
return (encr->encr_key); |
371 |
|
|
} |
372 |
|
|
|
373 |
|
|
struct ibuf * |
374 |
|
|
cipher_setiv(struct iked_cipher *encr, void *iv, size_t len) |
375 |
|
|
{ |
376 |
|
|
ibuf_release(encr->encr_iv); |
377 |
|
|
encr->encr_iv = NULL; |
378 |
|
|
if (iv != NULL) { |
379 |
|
|
if (len < encr->encr_ivlength) { |
380 |
|
|
log_debug("%s: invalid IV length %zu", __func__, len); |
381 |
|
|
return (NULL); |
382 |
|
|
} |
383 |
|
|
encr->encr_iv = ibuf_new(iv, encr->encr_ivlength); |
384 |
|
|
} else { |
385 |
|
|
/* Get new random IV */ |
386 |
|
|
encr->encr_iv = ibuf_random(encr->encr_ivlength); |
387 |
|
|
} |
388 |
|
|
if (encr->encr_iv == NULL) { |
389 |
|
|
log_debug("%s: failed to set IV", __func__); |
390 |
|
|
return (NULL); |
391 |
|
|
} |
392 |
|
|
return (encr->encr_iv); |
393 |
|
|
} |
394 |
|
|
|
395 |
|
|
void |
396 |
|
|
cipher_free(struct iked_cipher *encr) |
397 |
|
|
{ |
398 |
|
|
if (encr == NULL) |
399 |
|
|
return; |
400 |
|
|
if (encr->encr_ctx != NULL) { |
401 |
|
|
EVP_CIPHER_CTX_cleanup(encr->encr_ctx); |
402 |
|
|
free(encr->encr_ctx); |
403 |
|
|
} |
404 |
|
|
ibuf_release(encr->encr_key); |
405 |
|
|
free(encr); |
406 |
|
|
} |
407 |
|
|
|
408 |
|
|
void |
409 |
|
|
cipher_init(struct iked_cipher *encr, int enc) |
410 |
|
|
{ |
411 |
|
|
EVP_CipherInit_ex(encr->encr_ctx, encr->encr_priv, NULL, |
412 |
|
|
ibuf_data(encr->encr_key), ibuf_data(encr->encr_iv), enc); |
413 |
|
|
EVP_CIPHER_CTX_set_padding(encr->encr_ctx, 0); |
414 |
|
|
} |
415 |
|
|
|
416 |
|
|
void |
417 |
|
|
cipher_init_encrypt(struct iked_cipher *encr) |
418 |
|
|
{ |
419 |
|
|
cipher_init(encr, 1); |
420 |
|
|
} |
421 |
|
|
|
422 |
|
|
void |
423 |
|
|
cipher_init_decrypt(struct iked_cipher *encr) |
424 |
|
|
{ |
425 |
|
|
cipher_init(encr, 0); |
426 |
|
|
} |
427 |
|
|
|
428 |
|
|
void |
429 |
|
|
cipher_update(struct iked_cipher *encr, void *in, size_t inlen, |
430 |
|
|
void *out, size_t *outlen) |
431 |
|
|
{ |
432 |
|
|
int olen; |
433 |
|
|
|
434 |
|
|
olen = 0; |
435 |
|
|
if (!EVP_CipherUpdate(encr->encr_ctx, out, &olen, in, inlen)) { |
436 |
|
|
ca_sslerror(__func__); |
437 |
|
|
*outlen = 0; |
438 |
|
|
return; |
439 |
|
|
} |
440 |
|
|
*outlen = (size_t)olen; |
441 |
|
|
} |
442 |
|
|
|
443 |
|
|
void |
444 |
|
|
cipher_final(struct iked_cipher *encr, void *out, size_t *outlen) |
445 |
|
|
{ |
446 |
|
|
int olen; |
447 |
|
|
|
448 |
|
|
olen = 0; |
449 |
|
|
if (!EVP_CipherFinal_ex(encr->encr_ctx, out, &olen)) { |
450 |
|
|
ca_sslerror(__func__); |
451 |
|
|
*outlen = 0; |
452 |
|
|
return; |
453 |
|
|
} |
454 |
|
|
*outlen = (size_t)olen; |
455 |
|
|
} |
456 |
|
|
|
457 |
|
|
size_t |
458 |
|
|
cipher_length(struct iked_cipher *encr) |
459 |
|
|
{ |
460 |
|
|
return (encr->encr_length); |
461 |
|
|
} |
462 |
|
|
|
463 |
|
|
size_t |
464 |
|
|
cipher_keylength(struct iked_cipher *encr) |
465 |
|
|
{ |
466 |
|
|
if (encr->encr_fixedkey) |
467 |
|
|
return (encr->encr_fixedkey); |
468 |
|
|
|
469 |
|
|
/* Might return zero */ |
470 |
|
|
return (ibuf_length(encr->encr_key)); |
471 |
|
|
} |
472 |
|
|
|
473 |
|
|
size_t |
474 |
|
|
cipher_ivlength(struct iked_cipher *encr) |
475 |
|
|
{ |
476 |
|
|
return (encr->encr_ivlength); |
477 |
|
|
} |
478 |
|
|
|
479 |
|
|
size_t |
480 |
|
|
cipher_outlength(struct iked_cipher *encr, size_t inlen) |
481 |
|
|
{ |
482 |
|
|
return (roundup(inlen, encr->encr_length)); |
483 |
|
|
} |
484 |
|
|
|
485 |
|
|
struct iked_dsa * |
486 |
|
|
dsa_new(uint16_t id, struct iked_hash *prf, int sign) |
487 |
|
|
{ |
488 |
|
|
struct iked_dsa *dsap = NULL, dsa; |
489 |
|
|
|
490 |
|
|
bzero(&dsa, sizeof(dsa)); |
491 |
|
|
|
492 |
|
|
switch (id) { |
493 |
|
|
case IKEV2_AUTH_SIG: |
494 |
|
|
if (sign) |
495 |
|
|
dsa.dsa_priv = EVP_sha256(); /* XXX should be passed */ |
496 |
|
|
else |
497 |
|
|
dsa.dsa_priv = NULL; /* set later by dsa_init() */ |
498 |
|
|
break; |
499 |
|
|
case IKEV2_AUTH_RSA_SIG: |
500 |
|
|
/* RFC5996 says we SHOULD use SHA1 here */ |
501 |
|
|
dsa.dsa_priv = EVP_sha1(); |
502 |
|
|
break; |
503 |
|
|
case IKEV2_AUTH_SHARED_KEY_MIC: |
504 |
|
|
if (prf == NULL || prf->hash_priv == NULL) |
505 |
|
|
fatalx("dsa_new: invalid PRF"); |
506 |
|
|
dsa.dsa_priv = prf->hash_priv; |
507 |
|
|
dsa.dsa_hmac = 1; |
508 |
|
|
break; |
509 |
|
|
case IKEV2_AUTH_DSS_SIG: |
510 |
|
|
dsa.dsa_priv = EVP_dss1(); |
511 |
|
|
break; |
512 |
|
|
case IKEV2_AUTH_ECDSA_256: |
513 |
|
|
dsa.dsa_priv = EVP_sha256(); |
514 |
|
|
break; |
515 |
|
|
case IKEV2_AUTH_ECDSA_384: |
516 |
|
|
dsa.dsa_priv = EVP_sha384(); |
517 |
|
|
break; |
518 |
|
|
case IKEV2_AUTH_ECDSA_521: |
519 |
|
|
dsa.dsa_priv = EVP_sha512(); |
520 |
|
|
break; |
521 |
|
|
default: |
522 |
|
|
log_debug("%s: auth method %s not supported", __func__, |
523 |
|
|
print_map(id, ikev2_auth_map)); |
524 |
|
|
break; |
525 |
|
|
} |
526 |
|
|
|
527 |
|
|
if ((dsap = calloc(1, sizeof(*dsap))) == NULL) { |
528 |
|
|
log_debug("%s: alloc dsa ctx", __func__); |
529 |
|
|
|
530 |
|
|
return (NULL); |
531 |
|
|
} |
532 |
|
|
memcpy(dsap, &dsa, sizeof(*dsap)); |
533 |
|
|
|
534 |
|
|
dsap->dsa_method = id; |
535 |
|
|
dsap->dsa_sign = sign; |
536 |
|
|
|
537 |
|
|
if (dsap->dsa_hmac) { |
538 |
|
|
if ((dsap->dsa_ctx = calloc(1, sizeof(HMAC_CTX))) == NULL) { |
539 |
|
|
log_debug("%s: alloc hash ctx", __func__); |
540 |
|
|
dsa_free(dsap); |
541 |
|
|
return (NULL); |
542 |
|
|
} |
543 |
|
|
HMAC_CTX_init((HMAC_CTX *)dsap->dsa_ctx); |
544 |
|
|
} else { |
545 |
|
|
if ((dsap->dsa_ctx = EVP_MD_CTX_create()) == NULL) { |
546 |
|
|
log_debug("%s: alloc digest ctx", __func__); |
547 |
|
|
dsa_free(dsap); |
548 |
|
|
return (NULL); |
549 |
|
|
} |
550 |
|
|
} |
551 |
|
|
|
552 |
|
|
return (dsap); |
553 |
|
|
} |
554 |
|
|
|
555 |
|
|
struct iked_dsa * |
556 |
|
|
dsa_sign_new(uint16_t id, struct iked_hash *prf) |
557 |
|
|
{ |
558 |
|
|
return (dsa_new(id, prf, 1)); |
559 |
|
|
} |
560 |
|
|
|
561 |
|
|
struct iked_dsa * |
562 |
|
|
dsa_verify_new(uint16_t id, struct iked_hash *prf) |
563 |
|
|
{ |
564 |
|
|
return (dsa_new(id, prf, 0)); |
565 |
|
|
} |
566 |
|
|
|
567 |
|
|
void |
568 |
|
|
dsa_free(struct iked_dsa *dsa) |
569 |
|
|
{ |
570 |
|
|
if (dsa == NULL) |
571 |
|
|
return; |
572 |
|
|
if (dsa->dsa_hmac) { |
573 |
|
|
HMAC_CTX_cleanup((HMAC_CTX *)dsa->dsa_ctx); |
574 |
|
|
free(dsa->dsa_ctx); |
575 |
|
|
} else { |
576 |
|
|
EVP_MD_CTX_destroy((EVP_MD_CTX *)dsa->dsa_ctx); |
577 |
|
|
if (dsa->dsa_key) |
578 |
|
|
EVP_PKEY_free(dsa->dsa_key); |
579 |
|
|
if (dsa->dsa_cert) |
580 |
|
|
X509_free(dsa->dsa_cert); |
581 |
|
|
} |
582 |
|
|
|
583 |
|
|
ibuf_release(dsa->dsa_keydata); |
584 |
|
|
free(dsa); |
585 |
|
|
} |
586 |
|
|
|
587 |
|
|
struct ibuf * |
588 |
|
|
dsa_setkey(struct iked_dsa *dsa, void *key, size_t keylen, uint8_t type) |
589 |
|
|
{ |
590 |
|
|
BIO *rawcert = NULL; |
591 |
|
|
X509 *cert = NULL; |
592 |
|
|
RSA *rsa = NULL; |
593 |
|
|
EC_KEY *ec = NULL; |
594 |
|
|
EVP_PKEY *pkey = NULL; |
595 |
|
|
|
596 |
|
|
ibuf_release(dsa->dsa_keydata); |
597 |
|
|
if ((dsa->dsa_keydata = ibuf_new(key, keylen)) == NULL) { |
598 |
|
|
log_debug("%s: alloc signature key", __func__); |
599 |
|
|
return (NULL); |
600 |
|
|
} |
601 |
|
|
|
602 |
|
|
if ((rawcert = BIO_new_mem_buf(key, keylen)) == NULL) |
603 |
|
|
goto err; |
604 |
|
|
|
605 |
|
|
switch (type) { |
606 |
|
|
case IKEV2_CERT_X509_CERT: |
607 |
|
|
if ((cert = d2i_X509_bio(rawcert, NULL)) == NULL) |
608 |
|
|
goto sslerr; |
609 |
|
|
if ((pkey = X509_get_pubkey(cert)) == NULL) |
610 |
|
|
goto sslerr; |
611 |
|
|
dsa->dsa_cert = cert; |
612 |
|
|
dsa->dsa_key = pkey; |
613 |
|
|
break; |
614 |
|
|
case IKEV2_CERT_RSA_KEY: |
615 |
|
|
if (dsa->dsa_sign) { |
616 |
|
|
if ((rsa = d2i_RSAPrivateKey_bio(rawcert, |
617 |
|
|
NULL)) == NULL) |
618 |
|
|
goto sslerr; |
619 |
|
|
} else { |
620 |
|
|
if ((rsa = d2i_RSAPublicKey_bio(rawcert, |
621 |
|
|
NULL)) == NULL) |
622 |
|
|
goto sslerr; |
623 |
|
|
} |
624 |
|
|
|
625 |
|
|
if ((pkey = EVP_PKEY_new()) == NULL) |
626 |
|
|
goto sslerr; |
627 |
|
|
if (!EVP_PKEY_set1_RSA(pkey, rsa)) |
628 |
|
|
goto sslerr; |
629 |
|
|
|
630 |
|
|
RSA_free(rsa); /* pkey now has the reference */ |
631 |
|
|
dsa->dsa_cert = NULL; |
632 |
|
|
dsa->dsa_key = pkey; |
633 |
|
|
break; |
634 |
|
|
case IKEV2_CERT_ECDSA: |
635 |
|
|
if (dsa->dsa_sign) { |
636 |
|
|
if ((ec = d2i_ECPrivateKey_bio(rawcert, NULL)) == NULL) |
637 |
|
|
goto sslerr; |
638 |
|
|
} else { |
639 |
|
|
if ((ec = d2i_EC_PUBKEY_bio(rawcert, NULL)) == NULL) |
640 |
|
|
goto sslerr; |
641 |
|
|
} |
642 |
|
|
|
643 |
|
|
if ((pkey = EVP_PKEY_new()) == NULL) |
644 |
|
|
goto sslerr; |
645 |
|
|
if (!EVP_PKEY_set1_EC_KEY(pkey, ec)) |
646 |
|
|
goto sslerr; |
647 |
|
|
|
648 |
|
|
EC_KEY_free(ec); /* pkey now has the reference */ |
649 |
|
|
dsa->dsa_cert = NULL; |
650 |
|
|
dsa->dsa_key = pkey; |
651 |
|
|
break; |
652 |
|
|
default: |
653 |
|
|
if (dsa->dsa_hmac) |
654 |
|
|
break; |
655 |
|
|
log_debug("%s: unsupported key type", __func__); |
656 |
|
|
goto err; |
657 |
|
|
} |
658 |
|
|
|
659 |
|
|
return (dsa->dsa_keydata); |
660 |
|
|
|
661 |
|
|
sslerr: |
662 |
|
|
ca_sslerror(__func__); |
663 |
|
|
err: |
664 |
|
|
log_debug("%s: error", __func__); |
665 |
|
|
|
666 |
|
|
if (rsa != NULL) |
667 |
|
|
RSA_free(rsa); |
668 |
|
|
if (ec != NULL) |
669 |
|
|
EC_KEY_free(ec); |
670 |
|
|
if (pkey != NULL) |
671 |
|
|
EVP_PKEY_free(pkey); |
672 |
|
|
if (cert != NULL) |
673 |
|
|
X509_free(cert); |
674 |
|
|
if (rawcert != NULL) |
675 |
|
|
BIO_free(rawcert); |
676 |
|
|
ibuf_release(dsa->dsa_keydata); |
677 |
|
|
dsa->dsa_keydata = NULL; |
678 |
|
|
return (NULL); |
679 |
|
|
} |
680 |
|
|
|
681 |
|
|
int |
682 |
|
|
_dsa_verify_init(struct iked_dsa *dsa, const uint8_t *sig, size_t len) |
683 |
|
|
{ |
684 |
|
|
uint8_t oidlen; |
685 |
|
|
size_t i; |
686 |
|
|
int keytype; |
687 |
|
|
|
688 |
|
|
if (dsa->dsa_priv != NULL) |
689 |
|
|
return (0); |
690 |
|
|
/* |
691 |
|
|
* For IKEV2_AUTH_SIG the oid of the authentication signature |
692 |
|
|
* is encoded in the first bytes of the auth message. |
693 |
|
|
*/ |
694 |
|
|
if (dsa->dsa_method != IKEV2_AUTH_SIG) { |
695 |
|
|
log_debug("%s: dsa_priv not set for %s", __func__, |
696 |
|
|
print_map(dsa->dsa_method, ikev2_auth_map)); |
697 |
|
|
return (-1); |
698 |
|
|
} |
699 |
|
|
if (dsa->dsa_key == NULL) { |
700 |
|
|
log_debug("%s: dsa_key not set for %s", __func__, |
701 |
|
|
print_map(dsa->dsa_method, ikev2_auth_map)); |
702 |
|
|
return (-1); |
703 |
|
|
} |
704 |
|
|
keytype = EVP_PKEY_type(((EVP_PKEY *)dsa->dsa_key)->type); |
705 |
|
|
if (sig == NULL) { |
706 |
|
|
log_debug("%s: signature missing", __func__); |
707 |
|
|
return (-1); |
708 |
|
|
} |
709 |
|
|
if (len < sizeof(oidlen)) { |
710 |
|
|
log_debug("%s: signature (%zu) too small for oid length", |
711 |
|
|
__func__, len); |
712 |
|
|
return (-1); |
713 |
|
|
} |
714 |
|
|
memcpy(&oidlen, sig, sizeof(oidlen)); |
715 |
|
|
if (len < (size_t)oidlen + sizeof(oidlen)) { |
716 |
|
|
log_debug("%s: signature (%zu) too small for oid (%u)", |
717 |
|
|
__func__, len, oidlen); |
718 |
|
|
return (-1); |
719 |
|
|
} |
720 |
|
|
for (i = 0; i < nitems(schemes); i++) { |
721 |
|
|
if (keytype == schemes[i].sc_keytype && |
722 |
|
|
oidlen == schemes[i].sc_len && |
723 |
|
|
memcmp(sig + 1, schemes[i].sc_oid, |
724 |
|
|
schemes[i].sc_len) == 0) { |
725 |
|
|
dsa->dsa_priv = (*schemes[i].sc_md)(); |
726 |
|
|
log_debug("%s: signature scheme %zd selected", |
727 |
|
|
__func__, i); |
728 |
|
|
return (0); |
729 |
|
|
} |
730 |
|
|
} |
731 |
|
|
log_debug("%s: unsupported signature (%d)", __func__, oidlen); |
732 |
|
|
return (-1); |
733 |
|
|
} |
734 |
|
|
|
735 |
|
|
int |
736 |
|
|
dsa_init(struct iked_dsa *dsa, const void *buf, size_t len) |
737 |
|
|
{ |
738 |
|
|
int ret; |
739 |
|
|
|
740 |
|
|
if (dsa->dsa_hmac) { |
741 |
|
|
if (!HMAC_Init_ex(dsa->dsa_ctx, ibuf_data(dsa->dsa_keydata), |
742 |
|
|
ibuf_length(dsa->dsa_keydata), dsa->dsa_priv, NULL)) |
743 |
|
|
return (-1); |
744 |
|
|
return (0); |
745 |
|
|
} |
746 |
|
|
|
747 |
|
|
if (dsa->dsa_sign) |
748 |
|
|
ret = EVP_SignInit_ex(dsa->dsa_ctx, dsa->dsa_priv, NULL); |
749 |
|
|
else { |
750 |
|
|
if ((ret = _dsa_verify_init(dsa, buf, len)) != 0) |
751 |
|
|
return (ret); |
752 |
|
|
ret = EVP_VerifyInit_ex(dsa->dsa_ctx, dsa->dsa_priv, NULL); |
753 |
|
|
} |
754 |
|
|
|
755 |
|
|
return (ret ? 0 : -1); |
756 |
|
|
} |
757 |
|
|
|
758 |
|
|
int |
759 |
|
|
dsa_update(struct iked_dsa *dsa, const void *buf, size_t len) |
760 |
|
|
{ |
761 |
|
|
int ret = 1; |
762 |
|
|
|
763 |
|
|
if (dsa->dsa_hmac) |
764 |
|
|
ret = HMAC_Update(dsa->dsa_ctx, buf, len); |
765 |
|
|
else if (dsa->dsa_sign) |
766 |
|
|
ret = EVP_SignUpdate(dsa->dsa_ctx, buf, len); |
767 |
|
|
else |
768 |
|
|
ret = EVP_VerifyUpdate(dsa->dsa_ctx, buf, len); |
769 |
|
|
|
770 |
|
|
return (ret ? 0 : -1); |
771 |
|
|
} |
772 |
|
|
|
773 |
|
|
/* Prefix signature hash with encoded type */ |
774 |
|
|
int |
775 |
|
|
_dsa_sign_encode(struct iked_dsa *dsa, uint8_t *ptr, size_t *offp) |
776 |
|
|
{ |
777 |
|
|
int keytype; |
778 |
|
|
size_t i; |
779 |
|
|
|
780 |
|
|
if (offp) |
781 |
|
|
*offp = 0; |
782 |
|
|
if (dsa->dsa_method != IKEV2_AUTH_SIG) |
783 |
|
|
return (0); |
784 |
|
|
if (dsa->dsa_key == NULL) |
785 |
|
|
return (-1); |
786 |
|
|
keytype = EVP_PKEY_type(((EVP_PKEY *)dsa->dsa_key)->type); |
787 |
|
|
for (i = 0; i < nitems(schemes); i++) { |
788 |
|
|
/* XXX should avoid calling sc_md() each time... */ |
789 |
|
|
if (keytype == schemes[i].sc_keytype && |
790 |
|
|
(dsa->dsa_priv == (*schemes[i].sc_md)())) |
791 |
|
|
break; |
792 |
|
|
} |
793 |
|
|
if (i >= nitems(schemes)) |
794 |
|
|
return (-1); |
795 |
|
|
if (ptr) { |
796 |
|
|
ptr[0] = schemes[i].sc_len; |
797 |
|
|
memcpy(ptr + sizeof(ptr[0]), schemes[i].sc_oid, |
798 |
|
|
schemes[i].sc_len); |
799 |
|
|
} |
800 |
|
|
if (offp) |
801 |
|
|
*offp = sizeof(ptr[0]) + schemes[i].sc_len; |
802 |
|
|
return (0); |
803 |
|
|
} |
804 |
|
|
|
805 |
|
|
/* Export size of encoded signature hash type */ |
806 |
|
|
size_t |
807 |
|
|
dsa_prefix(struct iked_dsa *dsa) |
808 |
|
|
{ |
809 |
|
|
size_t off = 0; |
810 |
|
|
|
811 |
|
|
if (_dsa_sign_encode(dsa, NULL, &off) < 0) |
812 |
|
|
fatal("dsa_prefix: internal error"); |
813 |
|
|
return off; |
814 |
|
|
} |
815 |
|
|
|
816 |
|
|
size_t |
817 |
|
|
dsa_length(struct iked_dsa *dsa) |
818 |
|
|
{ |
819 |
|
|
if (dsa->dsa_hmac) |
820 |
|
|
return (EVP_MD_size(dsa->dsa_priv)); |
821 |
|
|
switch (dsa->dsa_method) { |
822 |
|
|
case IKEV2_AUTH_ECDSA_256: |
823 |
|
|
case IKEV2_AUTH_ECDSA_384: |
824 |
|
|
case IKEV2_AUTH_ECDSA_521: |
825 |
|
|
/* size of concat(r|s) */ |
826 |
|
|
return (2 * ((EVP_PKEY_bits(dsa->dsa_key) + 7) / 8)); |
827 |
|
|
} |
828 |
|
|
return (dsa_prefix(dsa) + EVP_PKEY_size(dsa->dsa_key)); |
829 |
|
|
} |
830 |
|
|
|
831 |
|
|
int |
832 |
|
|
_dsa_sign_ecdsa(struct iked_dsa *dsa, uint8_t *ptr, size_t len) |
833 |
|
|
{ |
834 |
|
|
ECDSA_SIG *obj = NULL; |
835 |
|
|
uint8_t *otmp = NULL, *tmp; |
836 |
|
|
const uint8_t *p; |
837 |
|
|
unsigned int tmplen; |
838 |
|
|
int ret = -1; |
839 |
|
|
int bnlen, off; |
840 |
|
|
|
841 |
|
|
if (len % 2) |
842 |
|
|
goto done; /* must be even */ |
843 |
|
|
bnlen = len/2; |
844 |
|
|
/* |
845 |
|
|
* (a) create DER signature into 'tmp' buffer |
846 |
|
|
* (b) convert buffer to ECDSA_SIG object |
847 |
|
|
* (c) concatenate the padded r|s BIGNUMS into 'ptr' |
848 |
|
|
*/ |
849 |
|
|
if ((tmplen = EVP_PKEY_size(dsa->dsa_key)) == 0) |
850 |
|
|
goto done; |
851 |
|
|
if ((otmp = tmp = calloc(1, tmplen)) == NULL) |
852 |
|
|
goto done; |
853 |
|
|
if (!EVP_SignFinal(dsa->dsa_ctx, tmp, &tmplen, dsa->dsa_key)) |
854 |
|
|
goto done; |
855 |
|
|
p = tmp; |
856 |
|
|
if (d2i_ECDSA_SIG(&obj, &p, tmplen) == NULL) |
857 |
|
|
goto done; |
858 |
|
|
if (BN_num_bytes(obj->r) > bnlen || BN_num_bytes(obj->s) > bnlen) |
859 |
|
|
goto done; |
860 |
|
|
memset(ptr, 0, len); |
861 |
|
|
off = bnlen - BN_num_bytes(obj->r); |
862 |
|
|
BN_bn2bin(obj->r, ptr + off); |
863 |
|
|
off = 2 * bnlen - BN_num_bytes(obj->s); |
864 |
|
|
BN_bn2bin(obj->s, ptr + off); |
865 |
|
|
ret = 0; |
866 |
|
|
done: |
867 |
|
|
free(otmp); |
868 |
|
|
if (obj) |
869 |
|
|
ECDSA_SIG_free(obj); |
870 |
|
|
return (ret); |
871 |
|
|
} |
872 |
|
|
|
873 |
|
|
ssize_t |
874 |
|
|
dsa_sign_final(struct iked_dsa *dsa, void *buf, size_t len) |
875 |
|
|
{ |
876 |
|
|
unsigned int siglen; |
877 |
|
|
size_t off = 0; |
878 |
|
|
uint8_t *ptr = buf; |
879 |
|
|
|
880 |
|
|
if (len < dsa_length(dsa)) |
881 |
|
|
return (-1); |
882 |
|
|
|
883 |
|
|
if (dsa->dsa_hmac) { |
884 |
|
|
if (!HMAC_Final(dsa->dsa_ctx, buf, &siglen)) |
885 |
|
|
return (-1); |
886 |
|
|
} else { |
887 |
|
|
switch (dsa->dsa_method) { |
888 |
|
|
case IKEV2_AUTH_ECDSA_256: |
889 |
|
|
case IKEV2_AUTH_ECDSA_384: |
890 |
|
|
case IKEV2_AUTH_ECDSA_521: |
891 |
|
|
if (_dsa_sign_ecdsa(dsa, buf, len) < 0) |
892 |
|
|
return (-1); |
893 |
|
|
siglen = len; |
894 |
|
|
break; |
895 |
|
|
default: |
896 |
|
|
if (_dsa_sign_encode(dsa, ptr, &off) < 0) |
897 |
|
|
return (-1); |
898 |
|
|
if (!EVP_SignFinal(dsa->dsa_ctx, ptr + off, &siglen, |
899 |
|
|
dsa->dsa_key)) |
900 |
|
|
return (-1); |
901 |
|
|
siglen += off; |
902 |
|
|
break; |
903 |
|
|
} |
904 |
|
|
} |
905 |
|
|
|
906 |
|
|
return (siglen); |
907 |
|
|
} |
908 |
|
|
|
909 |
|
|
int |
910 |
|
|
_dsa_verify_prepare(struct iked_dsa *dsa, uint8_t **sigp, size_t *lenp, |
911 |
|
|
uint8_t **freemep) |
912 |
|
|
{ |
913 |
|
|
ECDSA_SIG *obj = NULL; |
914 |
|
|
uint8_t *ptr = NULL; |
915 |
|
|
size_t bnlen, len, off; |
916 |
|
|
int ret = -1; |
917 |
|
|
|
918 |
|
|
*freemep = NULL; /* don't return garbage in case of an error */ |
919 |
|
|
|
920 |
|
|
switch (dsa->dsa_method) { |
921 |
|
|
case IKEV2_AUTH_SIG: |
922 |
|
|
/* |
923 |
|
|
* The first byte of the signature encodes the OID |
924 |
|
|
* prefix length which we need to skip. |
925 |
|
|
*/ |
926 |
|
|
off = (*sigp)[0] + 1; |
927 |
|
|
*sigp = *sigp + off; |
928 |
|
|
*lenp = *lenp - off; |
929 |
|
|
*freemep = NULL; |
930 |
|
|
ret = 0; |
931 |
|
|
break; |
932 |
|
|
case IKEV2_AUTH_ECDSA_256: |
933 |
|
|
case IKEV2_AUTH_ECDSA_384: |
934 |
|
|
case IKEV2_AUTH_ECDSA_521: |
935 |
|
|
/* |
936 |
|
|
* sigp points to concatenation r|s, while EVP_VerifyFinal() |
937 |
|
|
* expects the signature as a DER-encoded blob (of the two |
938 |
|
|
* values), so we need to convert the signature in a new |
939 |
|
|
* buffer (we cannot override the given buffer) and the caller |
940 |
|
|
* has to free this buffer ('freeme'). |
941 |
|
|
*/ |
942 |
|
|
if (*lenp < 64 || *lenp > 132 || *lenp % 2) |
943 |
|
|
goto done; |
944 |
|
|
bnlen = (*lenp)/2; |
945 |
|
|
/* sigp points to concatenation: r|s */ |
946 |
|
|
if ((obj = ECDSA_SIG_new()) == NULL || |
947 |
|
|
BN_bin2bn(*sigp, bnlen, obj->r) == NULL || |
948 |
|
|
BN_bin2bn(*sigp+bnlen, bnlen, obj->s) == NULL || |
949 |
|
|
(len = i2d_ECDSA_SIG(obj, &ptr)) == 0) |
950 |
|
|
goto done; |
951 |
|
|
*lenp = len; |
952 |
|
|
*sigp = ptr; |
953 |
|
|
*freemep = ptr; |
954 |
|
|
ptr = NULL; |
955 |
|
|
ret = 0; |
956 |
|
|
break; |
957 |
|
|
default: |
958 |
|
|
return (0); |
959 |
|
|
} |
960 |
|
|
done: |
961 |
|
|
free(ptr); |
962 |
|
|
if (obj) |
963 |
|
|
ECDSA_SIG_free(obj); |
964 |
|
|
return (ret); |
965 |
|
|
} |
966 |
|
|
|
967 |
|
|
ssize_t |
968 |
|
|
dsa_verify_final(struct iked_dsa *dsa, void *buf, size_t len) |
969 |
|
|
{ |
970 |
|
|
uint8_t sig[EVP_MAX_MD_SIZE]; |
971 |
|
|
uint8_t *ptr = buf, *freeme = NULL; |
972 |
|
|
unsigned int siglen = sizeof(sig); |
973 |
|
|
|
974 |
|
|
if (dsa->dsa_hmac) { |
975 |
|
|
if (!HMAC_Final(dsa->dsa_ctx, sig, &siglen)) |
976 |
|
|
return (-1); |
977 |
|
|
if (siglen != len || memcmp(buf, sig, siglen) != 0) |
978 |
|
|
return (-1); |
979 |
|
|
} else { |
980 |
|
|
if (_dsa_verify_prepare(dsa, &ptr, &len, &freeme) < 0) |
981 |
|
|
return (-1); |
982 |
|
|
if (EVP_VerifyFinal(dsa->dsa_ctx, ptr, len, |
983 |
|
|
dsa->dsa_key) != 1) { |
984 |
|
|
free(freeme); |
985 |
|
|
ca_sslerror(__func__); |
986 |
|
|
return (-1); |
987 |
|
|
} |
988 |
|
|
free(freeme); |
989 |
|
|
} |
990 |
|
|
|
991 |
|
|
return (0); |
992 |
|
|
} |