diff options
Diffstat (limited to 'main/openvpn/src/openvpn/crypto.c')
-rw-r--r-- | main/openvpn/src/openvpn/crypto.c | 441 |
1 files changed, 321 insertions, 120 deletions
diff --git a/main/openvpn/src/openvpn/crypto.c b/main/openvpn/src/openvpn/crypto.c index 59a6c737..1aaefbb4 100644 --- a/main/openvpn/src/openvpn/crypto.c +++ b/main/openvpn/src/openvpn/crypto.c @@ -65,6 +65,61 @@ #define CRYPT_ERROR(format) \ do { msg (D_CRYPT_ERRORS, "%s: " format, error_prefix); goto error_exit; } while (false) +static void +crypto_options_debug(const unsigned int flags, const char * prefix, + const struct crypto_options *opt) { + struct gc_arena gc = gc_new(); + + const char *encrypt_cipher = "none"; + const char *encrypt_impl_iv = "none"; + + const char *decrypt_cipher = "none"; + const char *decrypt_impl_iv = "none"; + + ASSERT(opt); + + const cipher_kt_t *cipher; + + if (opt->key_ctx_bi.encrypt.cipher) { + const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt; + + cipher = cipher_ctx_get_cipher_kt(ctx->cipher); + if (cipher) encrypt_cipher = cipher_kt_name(cipher); + + encrypt_impl_iv = ctx->implicit_iv_len + ? format_hex(ctx->implicit_iv, ctx->implicit_iv_len, 0, &gc) + : "NULL"; + } + + if (opt->key_ctx_bi.decrypt.cipher) { + const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt; + + cipher = cipher_ctx_get_cipher_kt(ctx->cipher); + if (cipher) decrypt_cipher = cipher_kt_name(cipher); + + decrypt_impl_iv = ctx->implicit_iv_len + ? format_hex(ctx->implicit_iv, ctx->implicit_iv_len, 0, &gc) + : "NULL"; + } + + dmsg(flags, "%s: crypto options (%p) {\n" + " flags = %x\n" + " encrypt cipher = %s\n" + " encr implicit iv = %s\n" + " decrypt cipher = %s\n" + " encr implicit iv = %s\n" + "}", + prefix, + opt, + opt->flags, + encrypt_cipher, + encrypt_impl_iv, + decrypt_cipher, + decrypt_impl_iv); + + gc_free(&gc); +} + /** * As memcmp(), but constant-time. * Returns 0 when data is equal, non-zero otherwise. @@ -85,22 +140,22 @@ memcmp_constant_time (const void *a, const void *b, size_t size) { void openvpn_encrypt (struct buffer *buf, struct buffer work, - const struct crypto_options *opt, - const struct frame* frame) + struct crypto_options *opt, const struct frame* frame) { struct gc_arena gc; + const cipher_kt_t *cipher_kt = NULL; gc_init (&gc); - if (buf->len > 0 && opt->key_ctx_bi) + if (buf->len > 0 && opt) { - struct key_ctx *ctx = &opt->key_ctx_bi->encrypt; + const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt; /* Do Encrypt from buf -> work */ if (ctx->cipher) { uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; const int iv_size = cipher_ctx_iv_length (ctx->cipher); - const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher); + cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher); int outlen; if (cipher_kt_mode_cbc(cipher_kt)) @@ -111,11 +166,11 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, if (opt->flags & CO_USE_IV) prng_bytes (iv_buf, iv_size); - /* Put packet ID in plaintext buffer or IV, depending on cipher mode */ - if (opt->packet_id) + /* Put packet ID in plaintext buffer */ + if (packet_id_initialized(&opt->packet_id)) { struct packet_id_net pin; - packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)); + packet_id_alloc_outgoing (&opt->packet_id.send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)); ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); } } @@ -124,15 +179,38 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, struct packet_id_net pin; struct buffer b; - ASSERT (opt->flags & CO_USE_IV); /* IV and packet-ID required */ - ASSERT (opt->packet_id); /* for this mode. */ + /* IV and packet-ID required for this mode. */ + ASSERT (opt->flags & CO_USE_IV); + ASSERT (packet_id_initialized(&opt->packet_id)); - packet_id_alloc_outgoing (&opt->packet_id->send, &pin, true); + packet_id_alloc_outgoing (&opt->packet_id.send, &pin, true); memset (iv_buf, 0, iv_size); buf_set_write (&b, iv_buf, iv_size); ASSERT (packet_id_write (&pin, &b, true, false)); } - else /* We only support CBC, CFB, or OFB modes right now */ + else if (cipher_kt_mode_aead (cipher_kt)) + { + struct packet_id_net pin; + struct buffer b; + + /* IV, packet-ID and implicit IV required for this mode. */ + ASSERT (opt->flags & CO_USE_IV); + ASSERT (iv_size >= 12); + ASSERT (packet_id_initialized(&opt->packet_id)); + ASSERT (ctx->implicit_iv_len); + + /* Prepare IV buffer */ + memset(iv_buf, 0, iv_size); + buf_set_write (&b, iv_buf, iv_size); + + /* IV starts with implicit IV (must be unique for each session) */ + ASSERT (buf_write (&b, ctx->implicit_iv, ctx->implicit_iv_len)); + + /* Append packet counter to make the IV unique for packet */ + packet_id_alloc_outgoing (&opt->packet_id.send, &pin, true); + ASSERT (packet_id_write (&pin, &b, false, false)); + } + else /* We only support CBC, CFB, OFB, or AEAD modes right now */ { ASSERT (0); } @@ -151,7 +229,8 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, ASSERT (cipher_ctx_reset(ctx->cipher, iv_buf)); /* Buffer overflow check */ - if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher))) + int block_size = cipher_ctx_block_size(ctx->cipher); + if (!buf_safe (&work, buf->len + block_size)) { msg (D_CRYPT_ERRORS, "ENCRYPT: buffer size error, bc=%d bo=%d bl=%d wc=%d wo=%d wl=%d cbs=%d", buf->capacity, @@ -160,10 +239,16 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, work.capacity, work.offset, work.len, - cipher_ctx_block_size (ctx->cipher)); + block_size); goto err; } + /* For AEAD ciphers, we need to update with the AD before ciphertext */ + if (cipher_kt_mode_aead (cipher_kt)) + { + ASSERT (cipher_ctx_update_ad (ctx->cipher, iv_buf, iv_size)); + } + /* Encrypt packet ID, payload */ ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))); work.len += outlen; @@ -179,9 +264,11 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, /* prepend the IV to the ciphertext */ if (opt->flags & CO_USE_IV) { - uint8_t *output = buf_prepend (&work, iv_size); + uint8_t *output = buf_prepend (&work, + iv_size - ctx->implicit_iv_len); ASSERT (output); - memcpy (output, iv_buf, iv_size); + memcpy (output, iv_buf + ctx->implicit_iv_len, + iv_size - ctx->implicit_iv_len); } dmsg (D_PACKET_CONTENT, "ENCRYPT TO: %s", @@ -189,10 +276,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, } else /* No Encryption */ { - if (opt->packet_id) + if (packet_id_initialized(&opt->packet_id)) { struct packet_id_net pin; - packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)); + packet_id_alloc_outgoing (&opt->packet_id.send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)); ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); } work = *buf; @@ -209,6 +296,15 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, ASSERT (output); hmac_ctx_final (ctx->hmac, output); } + else if (cipher_kt && cipher_kt_mode_aead(cipher_kt)) + { + int tag_len = cipher_kt_tag_size (cipher_kt); + uint8_t* output = NULL; + + output = buf_prepend (&work, tag_len); + ASSERT (output); + ASSERT (cipher_ctx_get_tag (ctx->cipher, output, tag_len)); + } *buf = work; } @@ -223,6 +319,30 @@ err: return; } +int verify_hmac(struct buffer *buf, struct key_ctx *ctx, int offset) +{ + uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed locally */ + int hmac_len = 0; + + hmac_ctx_reset(ctx->hmac); + /* Assume the length of the input HMAC */ + hmac_len = hmac_ctx_size (ctx->hmac); + + /* Authentication fails if insufficient data in packet for HMAC */ + if (buf->len - offset < hmac_len) + return 0; + + hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len + offset, + BLEN (buf) - hmac_len - offset); + hmac_ctx_final (ctx->hmac, local_hmac); + + /* Compare locally computed HMAC with packet HMAC */ + if (memcmp_constant_time (local_hmac, BPTR (buf) + offset, hmac_len) == 0) + return hmac_len; + + return 0; +} + /* * If (opt->flags & CO_USE_IV) is not NULL, we will read an IV from the packet. * @@ -233,64 +353,68 @@ err: */ bool openvpn_decrypt (struct buffer *buf, struct buffer work, - const struct crypto_options *opt, - const struct frame* frame) + struct crypto_options *opt, const struct frame* frame) { static const char error_prefix[] = "Authenticate/Decrypt packet error"; struct gc_arena gc; gc_init (&gc); - if (buf->len > 0 && opt->key_ctx_bi) + if (buf->len > 0 && opt) { - struct key_ctx *ctx = &opt->key_ctx_bi->decrypt; + const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt; struct packet_id_net pin; bool have_pin = false; + crypto_options_debug(D_CRYPTO_DEBUG, __func__, opt); + /* Verify the HMAC */ if (ctx->hmac) { - int hmac_len; - uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed locally */ - - hmac_ctx_reset(ctx->hmac); - - /* Assume the length of the input HMAC */ - hmac_len = hmac_ctx_size (ctx->hmac); - - /* Authentication fails if insufficient data in packet for HMAC */ - if (buf->len < hmac_len) - CRYPT_ERROR ("missing authentication info"); - - hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len, BLEN (buf) - hmac_len); - hmac_ctx_final (ctx->hmac, local_hmac); - - /* Compare locally computed HMAC with packet HMAC */ - if (memcmp_constant_time (local_hmac, BPTR (buf), hmac_len)) + int hmac_len = verify_hmac(buf, ctx, 0); + if (hmac_len == 0) CRYPT_ERROR ("packet HMAC authentication failed"); - ASSERT (buf_advance (buf, hmac_len)); } /* Decrypt packet ID + payload */ - if (ctx->cipher) { const int iv_size = cipher_ctx_iv_length (ctx->cipher); const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher); uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH]; + int tag_size = 0; + uint8_t tag_buf[MAX_HMAC_KEY_LENGTH]; /* tag of AEAD ciphertext */ int outlen; + int retval = 0; /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */ ASSERT (buf_init (&work, FRAME_HEADROOM_ADJ (frame, FRAME_HEADROOM_MARKER_DECRYPT))); + /* for AEAD ciphers, keep the tag value to feed in later */ + CLEAR (tag_buf); + if (cipher_kt_mode_aead(cipher_kt)) + { + tag_size = cipher_kt_tag_size(cipher_kt); + if (buf->len < tag_size) + CRYPT_ERROR ("missing tag"); + memcpy (tag_buf, BPTR (buf), tag_size); + ASSERT (buf_advance (buf, tag_size)); + } + /* use IV if user requested it */ CLEAR (iv_buf); if (opt->flags & CO_USE_IV) { - if (buf->len < iv_size) + ASSERT (ctx->implicit_iv_len <= iv_size); + if (ctx->implicit_iv_len + buf->len < iv_size) CRYPT_ERROR ("missing IV info"); - memcpy (iv_buf, BPTR (buf), iv_size); - ASSERT (buf_advance (buf, iv_size)); + + /* Get implicit part of IV */ + memcpy (iv_buf, ctx->implicit_iv, ctx->implicit_iv_len); + /* Read explicit part of IV from packet */ + memcpy (iv_buf + ctx->implicit_iv_len, BPTR (buf), + iv_size - ctx->implicit_iv_len); + ASSERT (buf_advance (buf, iv_size - ctx->implicit_iv_len)); } /* show the IV's initial state */ @@ -308,13 +432,25 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, if (!buf_safe (&work, buf->len)) CRYPT_ERROR ("buffer overflow"); + /* feed in tag and the authenticated data for AEAD mode ciphers */ + if (cipher_kt_mode_aead(cipher_kt)) + { + ASSERT (cipher_ctx_update_ad (ctx->cipher, iv_buf, iv_size)); + } + /* Decrypt packet ID, payload */ if (!cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf))) CRYPT_ERROR ("cipher update failed"); work.len += outlen; /* Flush the decryption buffer */ - if (!cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen)) + if (cipher_kt_mode_aead(cipher_kt)) { + retval = cipher_ctx_final_check_tag (ctx->cipher, BPTR (&work) + outlen, &outlen, tag_buf, tag_size); + } else { + retval = cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen); + } + + if (!retval) CRYPT_ERROR ("cipher final failed"); work.len += outlen; @@ -325,26 +461,30 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, { if (cipher_kt_mode_cbc(cipher_kt)) { - if (opt->packet_id) + if (packet_id_initialized(&opt->packet_id)) { if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM))) CRYPT_ERROR ("error reading CBC packet-id"); have_pin = true; } } - else if (cipher_kt_mode_ofb_cfb(cipher_kt)) + else if (cipher_kt_mode_ofb_cfb(cipher_kt) || + cipher_kt_mode_aead(cipher_kt)) { struct buffer b; ASSERT (opt->flags & CO_USE_IV); /* IV and packet-ID required */ - ASSERT (opt->packet_id); /* for this mode. */ + ASSERT (packet_id_initialized(&opt->packet_id)); /* for this mode. */ + + ASSERT (ctx->implicit_iv_len <= iv_size); + buf_set_read (&b, iv_buf + ctx->implicit_iv_len, + iv_size - ctx->implicit_iv_len); - buf_set_read (&b, iv_buf, iv_size); - if (!packet_id_read (&pin, &b, true)) - CRYPT_ERROR ("error reading CFB/OFB packet-id"); + if (!packet_id_read (&pin, &b, !ctx->implicit_iv_len)) + CRYPT_ERROR ("error reading CFB/OFB/AEAD packet-id"); have_pin = true; } - else /* We only support CBC, CFB, or OFB modes right now */ + else /* We only support CBC, CFB, OFB, or AEAD modes right now */ { ASSERT (0); } @@ -353,7 +493,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, else { work = *buf; - if (opt->packet_id) + if (packet_id_initialized(&opt->packet_id)) { if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM))) CRYPT_ERROR ("error reading packet-id"); @@ -363,12 +503,13 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, if (have_pin) { - packet_id_reap_test (&opt->packet_id->rec); - if (packet_id_test (&opt->packet_id->rec, &pin)) + packet_id_reap_test (&opt->packet_id.rec); + if (packet_id_test (&opt->packet_id.rec, &pin)) { - packet_id_add (&opt->packet_id->rec, &pin); - if (opt->pid_persist && (opt->flags & CO_PACKET_ID_LONG_FORM)) - packet_id_persist_save_obj (opt->pid_persist, opt->packet_id); + packet_id_add (&opt->packet_id.rec, &pin); + if (opt->pid_persist && (opt->flags & CO_PACKET_ID_LONG_FORM) && + !ctx->implicit_iv_len) + packet_id_persist_save_obj (opt->pid_persist, &opt->packet_id); } else { @@ -399,49 +540,17 @@ openvpn_decrypt (struct buffer *buf, struct buffer work, bool crypto_test_hmac (struct buffer *buf, const struct crypto_options *opt) { - struct gc_arena gc; - gc_init (&gc); - int offset = 4; /* 1 byte opcode + 3 bytes session-id */ - - if (buf->len > 0 && opt->key_ctx_bi) + if (buf->len > 0 && opt) { - struct key_ctx *ctx = &opt->key_ctx_bi->decrypt; + const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt; /* Verify the HMAC */ if (ctx->hmac) { - int hmac_len; - uint8_t local_hmac[MAX_HMAC_KEY_LENGTH]; /* HMAC of ciphertext computed locally */ - - hmac_ctx_reset(ctx->hmac); - - /* Assume the length of the input HMAC */ - hmac_len = hmac_ctx_size (ctx->hmac); - - /* Authentication fails if insufficient data in packet for HMAC */ - if ((buf->len - offset) < hmac_len) - { - gc_free (&gc); - return false; - } - - hmac_ctx_update (ctx->hmac, BPTR (buf) + offset + hmac_len, - BLEN (buf) - offset - hmac_len); - hmac_ctx_final (ctx->hmac, local_hmac); - - /* Compare locally computed HMAC with packet HMAC */ - if (memcmp_constant_time (local_hmac, BPTR (buf) + offset, hmac_len)) - { - gc_free (&gc); - return false; - } - - gc_free (&gc); - return true; + /* sizeof(uint32_t) comes from peer_id (3 bytes) and opcode (1 byte) */ + return verify_hmac(buf, ctx, sizeof(uint32_t)) != 0; } } - - gc_free (&gc); return false; } @@ -457,11 +566,30 @@ crypto_adjust_frame_parameters(struct frame *frame, bool packet_id, bool packet_id_long_form) { - frame_add_to_extra_frame (frame, - (packet_id ? packet_id_size (packet_id_long_form) : 0) + - ((cipher_defined && use_iv) ? cipher_kt_iv_size (kt->cipher) : 0) + - (cipher_defined ? cipher_kt_block_size (kt->cipher) : 0) + /* worst case padding expansion */ - kt->hmac_length); + size_t crypto_overhead = 0; + + if (packet_id) + crypto_overhead += packet_id_size (packet_id_long_form); + + if (cipher_defined) + { + if (use_iv) + crypto_overhead += cipher_kt_iv_size (kt->cipher); + + if (cipher_kt_mode_aead (kt->cipher)) + crypto_overhead += cipher_kt_tag_size (kt->cipher); + + if (cipher_kt_mode_cbc (kt->cipher)) + /* worst case padding expansion */ + crypto_overhead += cipher_kt_block_size (kt->cipher); + } + + crypto_overhead += kt->hmac_length; + + frame_add_to_extra_frame (frame, crypto_overhead); + + msg(D_MTU_DEBUG, "%s: Adjusting frame parameters for crypto by %zu bytes", + __func__, crypto_overhead); } /* @@ -471,8 +599,10 @@ void init_key_type (struct key_type *kt, const char *ciphername, bool ciphername_defined, const char *authname, bool authname_defined, int keysize, - bool cfb_ofb_allowed, bool warn) + bool tls_mode, bool warn) { + bool aead_cipher = false; + CLEAR (*kt); if (ciphername && ciphername_defined) { @@ -482,14 +612,14 @@ init_key_type (struct key_type *kt, const char *ciphername, kt->cipher_length = keysize; /* check legal cipher mode */ - { - if (!(cipher_kt_mode_cbc(kt->cipher) + aead_cipher = cipher_kt_mode_aead(kt->cipher); + if (!(cipher_kt_mode_cbc(kt->cipher) + || (tls_mode && aead_cipher) #ifdef ENABLE_OFB_CFB_MODE - || (cfb_ofb_allowed && cipher_kt_mode_ofb_cfb(kt->cipher)) + || (tls_mode && cipher_kt_mode_ofb_cfb(kt->cipher)) #endif - )) - msg (M_FATAL, "Cipher '%s' mode not supported", ciphername); - } + )) + msg (M_FATAL, "Cipher '%s' mode not supported", ciphername); } else { @@ -498,10 +628,12 @@ init_key_type (struct key_type *kt, const char *ciphername, } if (authname && authname_defined) { - kt->digest = md_kt_get (authname); - kt->hmac_length = md_kt_size (kt->digest); + if (!aead_cipher) { /* Ignore auth for AEAD ciphers */ + kt->digest = md_kt_get (authname); + kt->hmac_length = md_kt_size (kt->digest); + } } - else + else if (!aead_cipher) { if (warn) msg (M_WARN, "******* WARNING *******: null MAC specified, no authentication will be used"); @@ -525,7 +657,7 @@ init_key_ctx (struct key_ctx *ctx, struct key *key, msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key", prefix, - cipher_kt_name(kt->cipher), + translate_cipher_name_to_openvpn(cipher_kt_name(kt->cipher)), kt->cipher_length *8); dmsg (D_SHOW_KEYS, "%s: CIPHER KEY: %s", prefix, @@ -571,6 +703,12 @@ free_key_ctx (struct key_ctx *ctx) free(ctx->hmac); ctx->hmac = NULL; } + if (ctx->implicit_iv) + { + free(ctx->implicit_iv); + ctx->implicit_iv = 0; + } + ctx->implicit_iv_len = 0; } void @@ -580,6 +718,20 @@ free_key_ctx_bi (struct key_ctx_bi *ctx) free_key_ctx(&ctx->decrypt); } +bool +key_ctx_set_implicit_iv (struct key_ctx *ctx, const uint8_t *iv, size_t len) +{ + if (ctx->implicit_iv) free (ctx->implicit_iv); + + ctx->implicit_iv = malloc (len); + if (!ctx->implicit_iv) return false; + + ctx->implicit_iv_len = len; + memcpy (ctx->implicit_iv, iv, len); + + return true; +} + static bool key_is_zero (struct key *key, const struct key_type *kt) @@ -727,7 +879,7 @@ key2_print (const struct key2* k, } void -test_crypto (const struct crypto_options *co, struct frame* frame) +test_crypto (struct crypto_options *co, struct frame* frame) { int i, j; struct gc_arena gc = gc_new (); @@ -740,6 +892,22 @@ test_crypto (const struct crypto_options *co, struct frame* frame) /* init work */ ASSERT (buf_init (&work, FRAME_HEADROOM (frame))); +#ifdef HAVE_AEAD_CIPHER_MODES + /* init implicit IV */ + { + const cipher_kt_t *cipher = cipher_ctx_get_cipher_kt( + co->key_ctx_bi.encrypt.cipher); + + if (cipher_kt_mode_aead(cipher)) + { + key_ctx_set_implicit_iv(&co->key_ctx_bi.encrypt,\ + (const uint8_t *) "01234567", 8); + key_ctx_set_implicit_iv(&co->key_ctx_bi.decrypt, + (const uint8_t *) "01234567", 8); + } + } +#endif + msg (M_INFO, "Entering " PACKAGE_NAME " crypto self-test mode."); for (i = 1; i <= TUN_MTU_SIZE (frame); ++i) { @@ -792,13 +960,8 @@ get_tls_handshake_key (const struct key_type *key_type, if (passphrase_file && key_type->hmac_length) { struct key2 key2; - struct key_type kt = *key_type; struct key_direction_state kds; - /* for control channel we are only authenticating, not encrypting */ - kt.cipher_length = 0; - kt.cipher = NULL; - if (flags & GHK_INLINE) { /* key was specified inline, key text is in passphrase_file */ @@ -830,10 +993,10 @@ get_tls_handshake_key (const struct key_type *key_type, /* failed, now try to get hash from a freeform file */ hash_size = read_passphrase_hash (passphrase_file, - kt.digest, + key_type->digest, key2.keys[0].hmac, MAX_HMAC_KEY_LENGTH); - ASSERT (hash_size == kt.hmac_length); + ASSERT (hash_size == key_type->hmac_length); /* suceeded */ key2.n = 1; @@ -850,9 +1013,9 @@ get_tls_handshake_key (const struct key_type *key_type, /* initialize hmac key in both directions */ - init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], &kt, OPENVPN_OP_ENCRYPT, + init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], key_type, OPENVPN_OP_ENCRYPT, "Outgoing Control Channel Authentication"); - init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], &kt, OPENVPN_OP_DECRYPT, + init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], key_type, OPENVPN_OP_DECRYPT, "Incoming Control Channel Authentication"); CLEAR (key2); @@ -1508,4 +1671,42 @@ md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2) return memcmp(d1->digest, d2->digest, MD5_DIGEST_LENGTH) == 0; } +static const cipher_name_pair * +get_cipher_name_pair(const char *cipher_name) { + const cipher_name_pair *pair; + size_t i = 0; + + /* Search for a cipher name translation */ + for (; i < cipher_name_translation_table_count; i++) + { + pair = &cipher_name_translation_table[i]; + if (0 == strcmp (cipher_name, pair->openvpn_name) || + 0 == strcmp (cipher_name, pair->ssllib_name)) + return pair; + } + + /* Nothing found, return null */ + return NULL; +} + +const char * +translate_cipher_name_from_openvpn (const char *cipher_name) { + const cipher_name_pair *pair = get_cipher_name_pair(cipher_name); + + if (NULL == pair) + return cipher_name; + + return pair->ssllib_name; +} + +const char * +translate_cipher_name_to_openvpn (const char *cipher_name) { + const cipher_name_pair *pair = get_cipher_name_pair(cipher_name); + + if (NULL == pair) + return cipher_name; + + return pair->openvpn_name; +} + #endif /* ENABLE_CRYPTO */ |