From 6edfd973ebf8a33fc8b416e76622c4cd5d98736c Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Thu, 1 May 2014 16:06:25 +0000 Subject: Provide an EVP implementation for ChaCha. ok miod@ --- lib/libcrypto/chacha/chacha.c | 20 ++++++++++++ lib/libcrypto/chacha/chacha.h | 11 +++++++ lib/libcrypto/evp/c_allc.c | 4 +++ lib/libcrypto/evp/e_chacha.c | 65 +++++++++++++++++++++++++++++++++++++++ lib/libcrypto/evp/evp.h | 4 +++ lib/libcrypto/objects/objects.txt | 4 +++ 6 files changed, 108 insertions(+) create mode 100644 lib/libcrypto/evp/e_chacha.c diff --git a/lib/libcrypto/chacha/chacha.c b/lib/libcrypto/chacha/chacha.c index d76d64de4ab..1bc95f502d4 100644 --- a/lib/libcrypto/chacha/chacha.c +++ b/lib/libcrypto/chacha/chacha.c @@ -14,8 +14,28 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "chacha.h" #include "chacha-merged.c" +void +ChaCha_set_key(ChaCha_ctx *ctx, const unsigned char *key, uint32_t keybits) +{ + chacha_keysetup((chacha_ctx *)ctx, key, keybits); +} + +void +ChaCha_set_iv(ChaCha_ctx *ctx, const unsigned char *iv, + const unsigned char *counter) +{ + chacha_ivsetup((chacha_ctx *)ctx, iv, counter); +} + +void +ChaCha(ChaCha_ctx *ctx, unsigned char *out, const unsigned char *in, size_t len) +{ + chacha_encrypt_bytes((chacha_ctx *)ctx, in, out, (uint32_t)len); +} + void CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len, const unsigned char key[32], const unsigned char iv[8], size_t counter) diff --git a/lib/libcrypto/chacha/chacha.h b/lib/libcrypto/chacha/chacha.h index d66a719ae43..456d960ed9b 100644 --- a/lib/libcrypto/chacha/chacha.h +++ b/lib/libcrypto/chacha/chacha.h @@ -29,6 +29,17 @@ extern "C" { #endif +typedef struct { + unsigned int input[16]; +} ChaCha_ctx; + +void ChaCha_set_key(ChaCha_ctx *ctx, const unsigned char *key, + unsigned int keybits); +void ChaCha_set_iv(ChaCha_ctx *ctx, const unsigned char *iv, + const unsigned char *counter); +void ChaCha(ChaCha_ctx *ctx, unsigned char *out, const unsigned char *in, + size_t len); + void CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len, const unsigned char key[32], const unsigned char iv[8], size_t counter); diff --git a/lib/libcrypto/evp/c_allc.c b/lib/libcrypto/evp/c_allc.c index 2a45d435e58..2047b6cd61c 100644 --- a/lib/libcrypto/evp/c_allc.c +++ b/lib/libcrypto/evp/c_allc.c @@ -227,4 +227,8 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher_alias(SN_camellia_256_cbc,"CAMELLIA256"); EVP_add_cipher_alias(SN_camellia_256_cbc,"camellia256"); #endif + +#ifndef OPENSSL_NO_CHACHA + EVP_add_cipher(EVP_chacha20()); +#endif } diff --git a/lib/libcrypto/evp/e_chacha.c b/lib/libcrypto/evp/e_chacha.c new file mode 100644 index 00000000000..4a20186006a --- /dev/null +++ b/lib/libcrypto/evp/e_chacha.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef OPENSSL_NO_CHACHA + +#include +#include +#include + +#include "evp_locl.h" + +static int chacha_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); +static int chacha_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +static const EVP_CIPHER chacha20_cipher = { + .nid = NID_chacha20, + .block_size = 1, + .key_len = 32, + .iv_len = 8, + .flags = EVP_CIPH_STREAM_CIPHER, + .init = chacha_init, + .do_cipher = chacha_cipher, + .ctx_size = sizeof(ChaCha_ctx) +}; + +const EVP_CIPHER * +EVP_chacha20(void) +{ + return(&chacha20_cipher); +} + +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); + ChaCha_set_iv((ChaCha_ctx *)ctx->cipher_data, iv, NULL); + return 1; +} + +static int +chacha_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + size_t len) +{ + ChaCha((ChaCha_ctx *)ctx->cipher_data, out, in, len); + return 1; +} + +#endif diff --git a/lib/libcrypto/evp/evp.h b/lib/libcrypto/evp/evp.h index f43fe33b47d..fa98d4d93c7 100644 --- a/lib/libcrypto/evp/evp.h +++ b/lib/libcrypto/evp/evp.h @@ -838,6 +838,10 @@ const EVP_CIPHER *EVP_seed_cfb128(void); const EVP_CIPHER *EVP_seed_ofb(void); #endif +#ifndef OPENSSL_NO_CHACHA +const EVP_CIPHER *EVP_chacha20(void); +#endif + void OPENSSL_add_all_algorithms_noconf(void); void OPENSSL_add_all_algorithms_conf(void); diff --git a/lib/libcrypto/objects/objects.txt b/lib/libcrypto/objects/objects.txt index 487e0792553..bb44aa77a32 100644 --- a/lib/libcrypto/objects/objects.txt +++ b/lib/libcrypto/objects/objects.txt @@ -1309,3 +1309,7 @@ brainpool 1 13 : brainpoolP512r1 brainpool 1 14 : brainpoolP512t1 1 2 250 1 223 101 256 1 : FRP256v1 + +# ChaCha Stream Cipher +!Cname chacha20 + : ChaCha : chacha -- cgit v1.2.3