From 040c69f38462cc412a1cb654f5511253611ca375 Mon Sep 17 00:00:00 2001 From: tb <> Date: Sun, 26 Jan 2020 02:39:58 +0000 Subject: Adjust EVP_chacha20()'s behavior to match OpenSSL's semantics: The new IV is 128 bit long and is actually the 64 bit counter followed by 64 the bit initialization vector. This is needed by an upcoming change in OpenSSH and is a breaking change for all current callers. There are language bindings for Node.js, Rust and Erlang, but none of our ports use them. Note that EVP_chacha20() was first introduced in LibreSSL on May 1, 2014 while the entirely incompatible version in OpenSSL was committed on Dec 9, 2015. Initial diff from djm and myself, further refinements by djm. Ports grepping by sthen ok jsing --- src/lib/libcrypto/evp/e_chacha.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/lib/libcrypto/evp/e_chacha.c b/src/lib/libcrypto/evp/e_chacha.c index b63f586bba..bc496241e6 100644 --- a/src/lib/libcrypto/evp/e_chacha.c +++ b/src/lib/libcrypto/evp/e_chacha.c @@ -1,4 +1,4 @@ -/* $OpenBSD: e_chacha.c,v 1.5 2014/08/04 04:16:11 miod Exp $ */ +/* $OpenBSD: e_chacha.c,v 1.6 2020/01/26 02:39:58 tb Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -34,8 +34,9 @@ static const EVP_CIPHER chacha20_cipher = { .nid = NID_chacha20, .block_size = 1, .key_len = 32, - .iv_len = 8, - .flags = EVP_CIPH_STREAM_CIPHER, + .iv_len = 16, /* OpenSSL has 8 byte counter followed by 8 byte iv */ + .flags = EVP_CIPH_STREAM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CUSTOM_IV, .init = chacha_init, .do_cipher = chacha_cipher, .ctx_size = sizeof(ChaCha_ctx) @@ -51,10 +52,16 @@ static int chacha_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - ChaCha_set_key((ChaCha_ctx *)ctx->cipher_data, key, - EVP_CIPHER_CTX_key_length(ctx) * 8); - if (iv != NULL) - ChaCha_set_iv((ChaCha_ctx *)ctx->cipher_data, iv, NULL); + if (key != NULL) + ChaCha_set_key((ChaCha_ctx *)ctx->cipher_data, key, + EVP_CIPHER_CTX_key_length(ctx) * 8); + if (iv != NULL) { + const unsigned char *openssl_iv = iv + 8; + const unsigned char *counter = iv; + + ChaCha_set_iv((ChaCha_ctx *)ctx->cipher_data, openssl_iv, + counter); + } return 1; } -- cgit v1.2.3-55-g6feb