Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>
... | ... |
@@ -75,8 +75,8 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, |
75 | 75 |
if (ctx->cipher) |
76 | 76 |
{ |
77 | 77 |
uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; |
78 |
- const int iv_size = EVP_CIPHER_CTX_iv_length (ctx->cipher); |
|
79 |
- const unsigned int mode = EVP_CIPHER_CTX_mode (ctx->cipher); |
|
78 |
+ const int iv_size = cipher_ctx_iv_length (ctx->cipher); |
|
79 |
+ const unsigned int mode = cipher_ctx_mode (ctx->cipher); |
|
80 | 80 |
int outlen; |
81 | 81 |
|
82 | 82 |
if (mode == OPENVPN_MODE_CBC) |
... | ... |
@@ -124,10 +124,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, |
124 | 124 |
format_hex (BPTR (buf), BLEN (buf), 80, &gc)); |
125 | 125 |
|
126 | 126 |
/* cipher_ctx was already initialized with key & keylen */ |
127 |
- ASSERT (EVP_CipherInit_ov (ctx->cipher, NULL, NULL, iv_buf, DO_ENCRYPT)); |
|
127 |
+ ASSERT (cipher_ctx_reset(ctx->cipher, iv_buf)); |
|
128 | 128 |
|
129 | 129 |
/* Buffer overflow check */ |
130 |
- if (!buf_safe (&work, buf->len + EVP_CIPHER_CTX_block_size (ctx->cipher))) |
|
130 |
+ if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher))) |
|
131 | 131 |
{ |
132 | 132 |
msg (D_CRYPT_ERRORS, "ENCRYPT: buffer size error, bc=%d bo=%d bl=%d wc=%d wo=%d wl=%d cbs=%d", |
133 | 133 |
buf->capacity, |
... | ... |
@@ -136,16 +136,16 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, |
136 | 136 |
work.capacity, |
137 | 137 |
work.offset, |
138 | 138 |
work.len, |
139 |
- EVP_CIPHER_CTX_block_size (ctx->cipher)); |
|
139 |
+ cipher_ctx_block_size (ctx->cipher)); |
|
140 | 140 |
goto err; |
141 | 141 |
} |
142 | 142 |
|
143 | 143 |
/* Encrypt packet ID, payload */ |
144 |
- ASSERT (EVP_CipherUpdate_ov (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))); |
|
144 |
+ ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))); |
|
145 | 145 |
work.len += outlen; |
146 | 146 |
|
147 | 147 |
/* Flush the encryption buffer */ |
148 |
- ASSERT (EVP_CipherFinal (ctx->cipher, BPTR (&work) + outlen, &outlen)); |
|
148 |
+ ASSERT(cipher_ctx_final(ctx->cipher, BPTR (&work) + outlen, &outlen)); |
|
149 | 149 |
work.len += outlen; |
150 | 150 |
ASSERT (outlen == iv_size); |
151 | 151 |
|
... | ... |
@@ -248,8 +248,8 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, |
248 | 248 |
|
249 | 249 |
if (ctx->cipher) |
250 | 250 |
{ |
251 |
- const unsigned int mode = EVP_CIPHER_CTX_mode (ctx->cipher); |
|
252 |
- const int iv_size = EVP_CIPHER_CTX_iv_length (ctx->cipher); |
|
251 |
+ const unsigned int mode = cipher_ctx_mode (ctx->cipher); |
|
252 |
+ const int iv_size = cipher_ctx_iv_length (ctx->cipher); |
|
253 | 253 |
uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; |
254 | 254 |
int outlen; |
255 | 255 |
|
... | ... |
@@ -274,7 +274,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, |
274 | 274 |
CRYPT_ERROR ("missing payload"); |
275 | 275 |
|
276 | 276 |
/* ctx->cipher was already initialized with key & keylen */ |
277 |
- if (!EVP_CipherInit_ov (ctx->cipher, NULL, NULL, iv_buf, DO_DECRYPT)) |
|
277 |
+ if (!cipher_ctx_reset (ctx->cipher, iv_buf)) |
|
278 | 278 |
CRYPT_ERROR ("cipher init failed"); |
279 | 279 |
|
280 | 280 |
/* Buffer overflow check (should never happen) */ |
... | ... |
@@ -282,12 +282,12 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, |
282 | 282 |
CRYPT_ERROR ("buffer overflow"); |
283 | 283 |
|
284 | 284 |
/* Decrypt packet ID, payload */ |
285 |
- if (!EVP_CipherUpdate_ov (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))) |
|
285 |
+ if (!cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))) |
|
286 | 286 |
CRYPT_ERROR ("cipher update failed"); |
287 | 287 |
work.len += outlen; |
288 | 288 |
|
289 | 289 |
/* Flush the decryption buffer */ |
290 |
- if (!EVP_CipherFinal (ctx->cipher, BPTR (&work) + outlen, &outlen)) |
|
290 |
+ if (!cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen)) |
|
291 | 291 |
CRYPT_ERROR ("cipher final failed"); |
292 | 292 |
work.len += outlen; |
293 | 293 |
|
... | ... |
@@ -383,41 +383,6 @@ crypto_adjust_frame_parameters(struct frame *frame, |
383 | 383 |
kt->hmac_length); |
384 | 384 |
} |
385 | 385 |
|
386 |
-static void |
|
387 |
-init_cipher (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, |
|
388 |
- struct key *key, const struct key_type *kt, int enc, |
|
389 |
- const char *prefix) |
|
390 |
-{ |
|
391 |
- struct gc_arena gc = gc_new (); |
|
392 |
- |
|
393 |
- EVP_CIPHER_CTX_init (ctx); |
|
394 |
- if (!EVP_CipherInit_ov (ctx, cipher, NULL, NULL, enc)) |
|
395 |
- msg (M_SSLERR, "EVP cipher init #1"); |
|
396 |
-#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH |
|
397 |
- if (!EVP_CIPHER_CTX_set_key_length (ctx, kt->cipher_length)) |
|
398 |
- msg (M_SSLERR, "EVP set key size"); |
|
399 |
-#endif |
|
400 |
- if (!EVP_CipherInit_ov (ctx, NULL, key->cipher, NULL, enc)) |
|
401 |
- msg (M_SSLERR, "EVP cipher init #2"); |
|
402 |
- |
|
403 |
- msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key", |
|
404 |
- prefix, |
|
405 |
- OBJ_nid2sn (EVP_CIPHER_CTX_nid (ctx)), |
|
406 |
- EVP_CIPHER_CTX_key_length (ctx) * 8); |
|
407 |
- |
|
408 |
- /* make sure we used a big enough key */ |
|
409 |
- ASSERT (EVP_CIPHER_CTX_key_length (ctx) <= kt->cipher_length); |
|
410 |
- |
|
411 |
- dmsg (D_SHOW_KEYS, "%s: CIPHER KEY: %s", prefix, |
|
412 |
- format_hex (key->cipher, kt->cipher_length, 0, &gc)); |
|
413 |
- dmsg (D_CRYPTO_DEBUG, "%s: CIPHER block_size=%d iv_size=%d", |
|
414 |
- prefix, |
|
415 |
- EVP_CIPHER_CTX_block_size (ctx), |
|
416 |
- EVP_CIPHER_CTX_iv_length (ctx)); |
|
417 |
- |
|
418 |
- gc_free (&gc); |
|
419 |
-} |
|
420 |
- |
|
421 | 386 |
/* |
422 | 387 |
* Build a struct key_type. |
423 | 388 |
*/ |
... | ... |
@@ -476,8 +441,9 @@ init_key_ctx (struct key_ctx *ctx, struct key *key, |
476 | 476 |
CLEAR (*ctx); |
477 | 477 |
if (kt->cipher && kt->cipher_length > 0) |
478 | 478 |
{ |
479 |
- ALLOC_OBJ (ctx->cipher, EVP_CIPHER_CTX); |
|
480 |
- init_cipher (ctx->cipher, kt->cipher, key, kt, enc, prefix); |
|
479 |
+ ALLOC_OBJ(ctx->cipher, cipher_ctx_t); |
|
480 |
+ cipher_ctx_init (ctx->cipher, key->cipher, kt->cipher_length, |
|
481 |
+ kt->cipher, enc, prefix); |
|
481 | 482 |
} |
482 | 483 |
if (kt->digest && kt->hmac_length > 0) |
483 | 484 |
{ |
... | ... |
@@ -492,8 +458,8 @@ free_key_ctx (struct key_ctx *ctx) |
492 | 492 |
{ |
493 | 493 |
if (ctx->cipher) |
494 | 494 |
{ |
495 |
- EVP_CIPHER_CTX_cleanup (ctx->cipher); |
|
496 |
- free (ctx->cipher); |
|
495 |
+ cipher_ctx_cleanup(ctx->cipher); |
|
496 |
+ free(ctx->cipher); |
|
497 | 497 |
ctx->cipher = NULL; |
498 | 498 |
} |
499 | 499 |
if (ctx->hmac) |
... | ... |
@@ -182,6 +182,17 @@ struct key |
182 | 182 |
/**< %Key material for HMAC operations. */ |
183 | 183 |
}; |
184 | 184 |
|
185 |
+ |
|
186 |
+/** |
|
187 |
+ * Container for one set of OpenSSL cipher and/or HMAC contexts. |
|
188 |
+ * @ingroup control_processor |
|
189 |
+ */ |
|
190 |
+struct key_ctx |
|
191 |
+{ |
|
192 |
+ cipher_ctx_t *cipher; /**< Generic cipher %context. */ |
|
193 |
+ hmac_ctx_t *hmac; /**< Generic HMAC %context. */ |
|
194 |
+}; |
|
195 |
+ |
|
185 | 196 |
#define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */ |
186 | 197 |
#define KEY_DIRECTION_NORMAL 1 /* encrypt with keys[0], decrypt with keys[1] */ |
187 | 198 |
#define KEY_DIRECTION_INVERSE 2 /* encrypt with keys[1], decrypt with keys[0] */ |
... | ... |
@@ -224,16 +235,6 @@ struct key_direction_state |
224 | 224 |
}; |
225 | 225 |
|
226 | 226 |
/** |
227 |
- * Container for one set of OpenSSL cipher and/or HMAC contexts. |
|
228 |
- * @ingroup control_processor |
|
229 |
- */ |
|
230 |
-struct key_ctx |
|
231 |
-{ |
|
232 |
- EVP_CIPHER_CTX *cipher; /**< OpenSSL cipher %context. */ |
|
233 |
- HMAC_CTX *hmac; /**< OpenSSL HMAC %context. */ |
|
234 |
-}; |
|
235 |
- |
|
236 |
-/** |
|
237 | 227 |
* Container for two sets of OpenSSL cipher and/or HMAC contexts for both |
238 | 228 |
* sending and receiving directions. |
239 | 229 |
* @ingroup control_processor |
... | ... |
@@ -313,9 +314,6 @@ void init_key_type (struct key_type *kt, const char *ciphername, |
313 | 313 |
bool ciphername_defined, const char *authname, bool authname_defined, |
314 | 314 |
int keysize, bool cfb_ofb_allowed, bool warn); |
315 | 315 |
|
316 |
-/* enc parameter in init_key_ctx */ |
|
317 |
-#define DO_ENCRYPT 1 |
|
318 |
-#define DO_DECRYPT 0 |
|
319 | 316 |
/* |
320 | 317 |
* Key context functions |
321 | 318 |
*/ |
... | ... |
@@ -325,6 +323,7 @@ void init_key_ctx (struct key_ctx *ctx, struct key *key, |
325 | 325 |
const char *prefix); |
326 | 326 |
|
327 | 327 |
void free_key_ctx (struct key_ctx *ctx); |
328 |
+ |
|
328 | 329 |
void free_key_ctx_bi (struct key_ctx_bi *ctx); |
329 | 330 |
|
330 | 331 |
|
... | ... |
@@ -401,7 +400,6 @@ bool openvpn_decrypt (struct buffer *buf, struct buffer work, |
401 | 401 |
|
402 | 402 |
/** @} name Functions for performing security operations on data channel packets */ |
403 | 403 |
|
404 |
- |
|
405 | 404 |
void crypto_adjust_frame_parameters(struct frame *frame, |
406 | 405 |
const struct key_type* kt, |
407 | 406 |
bool cipher_defined, |
... | ... |
@@ -219,6 +219,106 @@ int cipher_kt_block_size (const cipher_kt_t *cipher_kt); |
219 | 219 |
bool cipher_kt_mode (const cipher_kt_t *cipher_kt); |
220 | 220 |
|
221 | 221 |
|
222 |
+/** |
|
223 |
+ * |
|
224 |
+ * Generic cipher functions |
|
225 |
+ * |
|
226 |
+ */ |
|
227 |
+ |
|
228 |
+/** |
|
229 |
+ * Initialise a cipher context, based on the given key and key type. |
|
230 |
+ * |
|
231 |
+ * @param ctx Cipher context. May not be NULL |
|
232 |
+ * @param key Buffer containing the key to use |
|
233 |
+ * @param key_len Length of the key, in bytes |
|
234 |
+ * @param kt Static cipher parameters to use |
|
235 |
+ * @param enc Whether to encrypt or decrypt (either |
|
236 |
+ * \c POLARSSL_OP_ENCRYPT or \c POLARSSL_OP_DECRYPT). |
|
237 |
+ * @param prefix Prefix to use for output. |
|
238 |
+ */ |
|
239 |
+void cipher_ctx_init (cipher_ctx_t *ctx, uint8_t *key, int key_len, |
|
240 |
+ const cipher_kt_t *kt, int enc, const char *prefix); |
|
241 |
+ |
|
242 |
+/** |
|
243 |
+ * Cleanup the specified context. |
|
244 |
+ * |
|
245 |
+ * @param ctx Cipher context to cleanup. |
|
246 |
+ */ |
|
247 |
+void cipher_ctx_cleanup (cipher_ctx_t *ctx); |
|
248 |
+ |
|
249 |
+/** |
|
250 |
+ * Returns the size of the IV used by the cipher, in bytes, or 0 if no IV is |
|
251 |
+ * used. |
|
252 |
+ * |
|
253 |
+ * @param ctx The cipher's context |
|
254 |
+ * |
|
255 |
+ * @return Size of the IV, in bytes, or \c 0 if the cipher does not |
|
256 |
+ * use an IV or ctx was NULL. |
|
257 |
+ */ |
|
258 |
+int cipher_ctx_iv_length (const cipher_ctx_t *ctx); |
|
259 |
+ |
|
260 |
+/** |
|
261 |
+ * Returns the block size of the cipher, in bytes. |
|
262 |
+ * |
|
263 |
+ * @param ctx The cipher's context |
|
264 |
+ * |
|
265 |
+ * @return Block size, in bytes, or 0 if ctx was NULL. |
|
266 |
+ */ |
|
267 |
+int cipher_ctx_block_size (const cipher_ctx_t *ctx); |
|
268 |
+ |
|
269 |
+/** |
|
270 |
+ * Returns the mode that the cipher runs in. |
|
271 |
+ * |
|
272 |
+ * @param ctx Cipher's context. May not be NULL. |
|
273 |
+ * |
|
274 |
+ * @return Cipher mode, either \c OPENVPN_MODE_CBC, \c |
|
275 |
+ * OPENVPN_MODE_OFB or \c OPENVPN_MODE_CFB |
|
276 |
+ */ |
|
277 |
+int cipher_ctx_mode (const cipher_ctx_t *ctx); |
|
278 |
+ |
|
279 |
+/** |
|
280 |
+ * Resets the given cipher context, setting the IV to the specified value. |
|
281 |
+ * Preserves the associated key information. |
|
282 |
+ * |
|
283 |
+ * @param ctx Cipher's context. May not be NULL. |
|
284 |
+ * @param iv_buf The IV to use. |
|
285 |
+ * |
|
286 |
+ * @return \c 0 on failure, \c 1 on success. |
|
287 |
+ */ |
|
288 |
+int cipher_ctx_reset (cipher_ctx_t *ctx, uint8_t *iv_buf); |
|
289 |
+ |
|
290 |
+/** |
|
291 |
+ * Updates the given cipher context, encrypting data in the source buffer, and |
|
292 |
+ * placing any complete blocks in the destination buffer. |
|
293 |
+ * |
|
294 |
+ * Note that if a complete block cannot be written, data is cached in the |
|
295 |
+ * context, and emitted at a later call to \c cipher_ctx_update, or by a call |
|
296 |
+ * to \c cipher_ctx_final(). This implies that dst should have enough room for |
|
297 |
+ * src_len + \c cipher_ctx_block_size() - 1. |
|
298 |
+ * |
|
299 |
+ * @param ctx Cipher's context. May not be NULL. |
|
300 |
+ * @param dst Destination buffer |
|
301 |
+ * @param dst_len Length of the destination buffer, in bytes |
|
302 |
+ * @param src Source buffer |
|
303 |
+ * @param src_len Length of the source buffer, in bytes |
|
304 |
+ * |
|
305 |
+ * @return \c 0 on failure, \c 1 on success. |
|
306 |
+ */ |
|
307 |
+int cipher_ctx_update (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len, |
|
308 |
+ uint8_t *src, int src_len); |
|
309 |
+ |
|
310 |
+/** |
|
311 |
+ * Pads the final cipher block using PKCS padding, and output to the destination |
|
312 |
+ * buffer. |
|
313 |
+ * |
|
314 |
+ * @param ctx Cipher's context. May not be NULL. |
|
315 |
+ * @param dst Destination buffer |
|
316 |
+ * @param dst_len Length of the destination buffer, in bytes |
|
317 |
+ * |
|
318 |
+ * @return \c 0 on failure, \c 1 on success. |
|
319 |
+ */ |
|
320 |
+int cipher_ctx_final (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len); |
|
321 |
+ |
|
222 | 322 |
/* |
223 | 323 |
* |
224 | 324 |
* Generic message digest information functions |
... | ... |
@@ -560,6 +560,95 @@ cipher_kt_mode (const EVP_CIPHER *cipher_kt) |
560 | 560 |
return EVP_CIPHER_mode (cipher_kt); |
561 | 561 |
} |
562 | 562 |
|
563 |
+/* |
|
564 |
+ * |
|
565 |
+ * Generic cipher context functions |
|
566 |
+ * |
|
567 |
+ */ |
|
568 |
+ |
|
569 |
+ |
|
570 |
+void |
|
571 |
+cipher_ctx_init (EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, |
|
572 |
+ const EVP_CIPHER *kt, int enc, const char *prefix) |
|
573 |
+{ |
|
574 |
+ struct gc_arena gc = gc_new (); |
|
575 |
+ |
|
576 |
+ ASSERT(NULL != kt && NULL != ctx); |
|
577 |
+ |
|
578 |
+ CLEAR (*ctx); |
|
579 |
+ |
|
580 |
+ EVP_CIPHER_CTX_init (ctx); |
|
581 |
+ if (!EVP_CipherInit_ov (ctx, kt, NULL, NULL, enc)) |
|
582 |
+ msg (M_SSLERR, "EVP cipher init #1"); |
|
583 |
+#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH |
|
584 |
+ if (!EVP_CIPHER_CTX_set_key_length (ctx, key_len)) |
|
585 |
+ msg (M_SSLERR, "EVP set key size"); |
|
586 |
+#endif |
|
587 |
+ if (!EVP_CipherInit_ov (ctx, NULL, key, NULL, enc)) |
|
588 |
+ msg (M_SSLERR, "EVP cipher init #2"); |
|
589 |
+ |
|
590 |
+ msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key", |
|
591 |
+ prefix, |
|
592 |
+ OBJ_nid2sn (EVP_CIPHER_CTX_nid (ctx)), |
|
593 |
+ EVP_CIPHER_CTX_key_length (ctx) * 8); |
|
594 |
+ |
|
595 |
+ /* make sure we used a big enough key */ |
|
596 |
+ ASSERT (EVP_CIPHER_CTX_key_length (ctx) <= key_len); |
|
597 |
+ |
|
598 |
+ dmsg (D_SHOW_KEYS, "%s: CIPHER KEY: %s", prefix, |
|
599 |
+ format_hex (key, key_len, 0, &gc)); |
|
600 |
+ dmsg (D_CRYPTO_DEBUG, "%s: CIPHER block_size=%d iv_size=%d", |
|
601 |
+ prefix, |
|
602 |
+ EVP_CIPHER_CTX_block_size (ctx), |
|
603 |
+ EVP_CIPHER_CTX_iv_length (ctx)); |
|
604 |
+ |
|
605 |
+ gc_free (&gc); |
|
606 |
+} |
|
607 |
+ |
|
608 |
+void |
|
609 |
+cipher_ctx_cleanup (EVP_CIPHER_CTX *ctx) |
|
610 |
+{ |
|
611 |
+ EVP_CIPHER_CTX_cleanup (ctx); |
|
612 |
+} |
|
613 |
+ |
|
614 |
+int |
|
615 |
+cipher_ctx_iv_length (const EVP_CIPHER_CTX *ctx) |
|
616 |
+{ |
|
617 |
+ return EVP_CIPHER_CTX_iv_length (ctx); |
|
618 |
+} |
|
619 |
+ |
|
620 |
+int |
|
621 |
+cipher_ctx_block_size(const EVP_CIPHER_CTX *ctx) |
|
622 |
+{ |
|
623 |
+ return EVP_CIPHER_CTX_block_size (ctx); |
|
624 |
+} |
|
625 |
+ |
|
626 |
+int |
|
627 |
+cipher_ctx_mode (const EVP_CIPHER_CTX *ctx) |
|
628 |
+{ |
|
629 |
+ return EVP_CIPHER_CTX_mode (ctx); |
|
630 |
+} |
|
631 |
+ |
|
632 |
+int |
|
633 |
+cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf) |
|
634 |
+{ |
|
635 |
+ return EVP_CipherInit_ov (ctx, NULL, NULL, iv_buf, -1); |
|
636 |
+} |
|
637 |
+ |
|
638 |
+int |
|
639 |
+cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len, |
|
640 |
+ uint8_t *src, int src_len) |
|
641 |
+{ |
|
642 |
+ return EVP_CipherUpdate_ov (ctx, dst, dst_len, src, src_len); |
|
643 |
+} |
|
644 |
+ |
|
645 |
+int |
|
646 |
+cipher_ctx_final (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len) |
|
647 |
+{ |
|
648 |
+ return EVP_CipherFinal (ctx, dst, dst_len); |
|
649 |
+} |
|
650 |
+ |
|
651 |
+ |
|
563 | 652 |
void |
564 | 653 |
cipher_des_encrypt_ecb (const unsigned char key[8], |
565 | 654 |
unsigned char *src, |