diff options
Diffstat (limited to 'lang/erlang-runtime19/files/patch-OpenSSL-1.1-b')
-rw-r--r-- | lang/erlang-runtime19/files/patch-OpenSSL-1.1-b | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/lang/erlang-runtime19/files/patch-OpenSSL-1.1-b b/lang/erlang-runtime19/files/patch-OpenSSL-1.1-b new file mode 100644 index 000000000000..781d5c687d9d --- /dev/null +++ b/lang/erlang-runtime19/files/patch-OpenSSL-1.1-b @@ -0,0 +1,293 @@ +From 4dddb3c0b286e13f2cbccb0cdaa4bffcfee60033 Mon Sep 17 00:00:00 2001 +From: Yuki Ito <yuki@gnnk.net> +Date: Tue, 20 Dec 2016 17:45:51 +0900 +Subject: [PATCH] crypto: Support chacha20_poly1305 + +This commit reactivates chacha20_poly1305 and fixes the imprementation +for the released OpenSSL 1.1.0 or later. +--- + lib/crypto/c_src/crypto.c | 152 ++++++++++++------------------- + lib/crypto/test/crypto_SUITE.erl | 49 ++++++++-- + 2 files changed, 101 insertions(+), 100 deletions(-) + +diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c +index 0031f9b9620..68784cd24c9 100644 +--- lib/crypto/c_src/crypto.c ++++ lib/crypto/c_src/crypto.c +@@ -117,7 +117,7 @@ + # endif + #endif + +-#if defined(NID_chacha20) && !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) ++#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,1,0) + # define HAVE_CHACHA20_POLY1305 + #endif + +@@ -131,20 +131,6 @@ + #include <openssl/ecdsa.h> + #endif + +-#if defined(HAVE_CHACHA20_POLY1305) +-#include <openssl/chacha.h> +-#include <openssl/poly1305.h> +- +-#if !defined(CHACHA20_NONCE_LEN) +-# define CHACHA20_NONCE_LEN 8 +-#endif +-#if !defined(POLY1305_TAG_LEN) +-# define POLY1305_TAG_LEN 16 +-#endif +- +-#endif +- +- + #ifdef VALGRIND + # include <valgrind/memcheck.h> + +@@ -2038,71 +2024,61 @@ + } + #endif /* HAVE_GCM_EVP_DECRYPT_BUG */ + +-#if defined(HAVE_CHACHA20_POLY1305) +-static void +-poly1305_update_with_length(poly1305_state *poly1305, +- const unsigned char *data, size_t data_len) +-{ +- size_t j = data_len; +- unsigned char length_bytes[8]; +- unsigned i; + +- for (i = 0; i < sizeof(length_bytes); i++) { +- length_bytes[i] = j; +- j >>= 8; +- } +- +- CRYPTO_poly1305_update(poly1305, data, data_len); +- CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); +-} +-#endif +- + static ERL_NIF_TERM chacha20_poly1305_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) + {/* (Key,Iv,AAD,In) */ + #if defined(HAVE_CHACHA20_POLY1305) ++ EVP_CIPHER_CTX *ctx; ++ const EVP_CIPHER *cipher = NULL; + ErlNifBinary key, iv, aad, in; +- unsigned char *outp; ++ unsigned char *outp, *tagp; + ERL_NIF_TERM out, out_tag; +- ErlNifUInt64 in_len_64; +- unsigned char poly1305_key[32]; +- poly1305_state poly1305; ++ int len; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 32 +- || !enif_inspect_binary(env, argv[1], &iv) || iv.size != CHACHA20_NONCE_LEN ++ || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0 || iv.size > 16 + || !enif_inspect_iolist_as_binary(env, argv[2], &aad) + || !enif_inspect_iolist_as_binary(env, argv[3], &in)) { + return enif_make_badarg(env); + } + +- /* Take from OpenSSL patch set/LibreSSL: +- * +- * The underlying ChaCha implementation may not overflow the block +- * counter into the second counter word. Therefore we disallow +- * individual operations that work on more than 2TB at a time. +- * in_len_64 is needed because, on 32-bit platforms, size_t is only +- * 32-bits and this produces a warning because it's always false. +- * Casting to uint64_t inside the conditional is not sufficient to stop +- * the warning. */ +- in_len_64 = in.size; +- if (in_len_64 >= (1ULL << 32) * 64 - 64) +- return enif_make_badarg(env); ++ cipher = EVP_chacha20_poly1305(); + +- memset(poly1305_key, 0, sizeof(poly1305_key)); +- CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key.data, iv.data, 0); ++ ctx = EVP_CIPHER_CTX_new(); + ++ if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) ++ goto out_err; ++ ++ EVP_CIPHER_CTX_set_padding(ctx, 0); ++ ++ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv.size, NULL) != 1) ++ goto out_err; ++ if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1) ++ goto out_err; ++ if (EVP_EncryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1) ++ goto out_err; ++ + outp = enif_make_new_binary(env, in.size, &out); + +- CRYPTO_poly1305_init(&poly1305, poly1305_key); +- poly1305_update_with_length(&poly1305, aad.data, aad.size); +- CRYPTO_chacha_20(outp, in.data, in.size, key.data, iv.data, 1); +- poly1305_update_with_length(&poly1305, outp, in.size); ++ if (EVP_EncryptUpdate(ctx, outp, &len, in.data, in.size) != 1) ++ goto out_err; ++ if (EVP_EncryptFinal_ex(ctx, outp+len, &len) != 1) ++ goto out_err; + +- CRYPTO_poly1305_finish(&poly1305, enif_make_new_binary(env, POLY1305_TAG_LEN, &out_tag)); ++ tagp = enif_make_new_binary(env, 16, &out_tag); + ++ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, tagp) != 1) ++ goto out_err; ++ ++ EVP_CIPHER_CTX_free(ctx); ++ + CONSUME_REDS(env, in); + + return enif_make_tuple2(env, out, out_tag); + ++out_err: ++ EVP_CIPHER_CTX_free(ctx); ++ return atom_error; + #else + return enif_raise_exception(env, atom_notsup); + #endif +@@ -2111,53 +2087,52 @@ + static ERL_NIF_TERM chacha20_poly1305_decrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) + {/* (Key,Iv,AAD,In,Tag) */ + #if defined(HAVE_CHACHA20_POLY1305) ++ EVP_CIPHER_CTX *ctx; ++ const EVP_CIPHER *cipher = NULL; + ErlNifBinary key, iv, aad, in, tag; + unsigned char *outp; + ERL_NIF_TERM out; +- ErlNifUInt64 in_len_64; +- unsigned char poly1305_key[32]; +- unsigned char mac[POLY1305_TAG_LEN]; +- poly1305_state poly1305; ++ int len; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 32 +- || !enif_inspect_binary(env, argv[1], &iv) || iv.size != CHACHA20_NONCE_LEN ++ || !enif_inspect_binary(env, argv[1], &iv) || iv.size == 0 || iv.size > 16 + || !enif_inspect_iolist_as_binary(env, argv[2], &aad) + || !enif_inspect_iolist_as_binary(env, argv[3], &in) +- || !enif_inspect_iolist_as_binary(env, argv[4], &tag) || tag.size != POLY1305_TAG_LEN) { ++ || !enif_inspect_iolist_as_binary(env, argv[4], &tag) || tag.size != 16) { + return enif_make_badarg(env); + } + +- /* Take from OpenSSL patch set/LibreSSL: +- * +- * The underlying ChaCha implementation may not overflow the block +- * counter into the second counter word. Therefore we disallow +- * individual operations that work on more than 2TB at a time. +- * in_len_64 is needed because, on 32-bit platforms, size_t is only +- * 32-bits and this produces a warning because it's always false. +- * Casting to uint64_t inside the conditional is not sufficient to stop +- * the warning. */ +- in_len_64 = in.size; +- if (in_len_64 >= (1ULL << 32) * 64 - 64) +- return enif_make_badarg(env); ++ cipher = EVP_chacha20_poly1305(); + +- memset(poly1305_key, 0, sizeof(poly1305_key)); +- CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key.data, iv.data, 0); ++ ctx = EVP_CIPHER_CTX_new(); + +- CRYPTO_poly1305_init(&poly1305, poly1305_key); +- poly1305_update_with_length(&poly1305, aad.data, aad.size); +- poly1305_update_with_length(&poly1305, in.data, in.size); +- CRYPTO_poly1305_finish(&poly1305, mac); ++ if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) ++ goto out_err; ++ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv.size, NULL) != 1) ++ goto out_err; ++ if (EVP_DecryptInit_ex(ctx, NULL, NULL, key.data, iv.data) != 1) ++ goto out_err; ++ if (EVP_DecryptUpdate(ctx, NULL, &len, aad.data, aad.size) != 1) ++ goto out_err; + +- if (memcmp(mac, tag.data, POLY1305_TAG_LEN) != 0) +- return atom_error; +- + outp = enif_make_new_binary(env, in.size, &out); + +- CRYPTO_chacha_20(outp, in.data, in.size, key.data, iv.data, 1); ++ if (EVP_DecryptUpdate(ctx, outp, &len, in.data, in.size) != 1) ++ goto out_err; ++ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag.size, tag.data) != 1) ++ goto out_err; ++ if (EVP_DecryptFinal_ex(ctx, outp+len, &len) != 1) ++ goto out_err; + ++ EVP_CIPHER_CTX_free(ctx); ++ + CONSUME_REDS(env, in); + + return out; ++ ++out_err: ++ EVP_CIPHER_CTX_free(ctx); ++ return atom_error; + #else + return enif_raise_exception(env, atom_notsup); + #endif +diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl +index 0c3b7a0445d..31f4e89ffe1 100644 +--- lib/crypto/test/crypto_SUITE.erl ++++ lib/crypto/test/crypto_SUITE.erl +@@ -2249,16 +2249,49 @@ aes_gcm() -> + 1} %% TagLength + ]. + +-%% http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04 ++%% https://tools.ietf.org/html/rfc7539#appendix-A.5 + chacha20_poly1305() -> + [ +- {chacha20_poly1305, hexstr2bin("4290bcb154173531f314af57f3be3b500" %% Key +- "6da371ece272afa1b5dbdd1100a1007"), +- hexstr2bin("86d09974840bded2a5ca"), %% PlainText +- hexstr2bin("cd7cf67be39c794a"), %% Nonce +- hexstr2bin("87e229d4500845a079c0"), %% AAD +- hexstr2bin("e3e446f7ede9a19b62a4"), %% CipherText +- hexstr2bin("677dabf4e3d24b876bb284753896e1d6")} %% CipherTag ++ {chacha20_poly1305, ++ hexstr2bin("1c9240a5eb55d38af333888604f6b5f0" %% Key ++ "473917c1402b80099dca5cbc207075c0"), ++ hexstr2bin("496e7465726e65742d44726166747320" %% PlainText ++ "61726520647261667420646f63756d65" ++ "6e74732076616c696420666f72206120" ++ "6d6178696d756d206f6620736978206d" ++ "6f6e74687320616e64206d6179206265" ++ "20757064617465642c207265706c6163" ++ "65642c206f72206f62736f6c65746564" ++ "206279206f7468657220646f63756d65" ++ "6e747320617420616e792074696d652e" ++ "20497420697320696e617070726f7072" ++ "6961746520746f2075736520496e7465" ++ "726e65742d4472616674732061732072" ++ "65666572656e6365206d617465726961" ++ "6c206f7220746f206369746520746865" ++ "6d206f74686572207468616e20617320" ++ "2fe2809c776f726b20696e2070726f67" ++ "726573732e2fe2809d"), ++ hexstr2bin("000000000102030405060708"), %% Nonce ++ hexstr2bin("f33388860000000000004e91"), %% AAD ++ hexstr2bin("64a0861575861af460f062c79be643bd" %% CipherText ++ "5e805cfd345cf389f108670ac76c8cb2" ++ "4c6cfc18755d43eea09ee94e382d26b0" ++ "bdb7b73c321b0100d4f03b7f355894cf" ++ "332f830e710b97ce98c8a84abd0b9481" ++ "14ad176e008d33bd60f982b1ff37c855" ++ "9797a06ef4f0ef61c186324e2b350638" ++ "3606907b6a7c02b0f9f6157b53c867e4" ++ "b9166c767b804d46a59b5216cde7a4e9" ++ "9040c5a40433225ee282a1b0a06c523e" ++ "af4534d7f83fa1155b0047718cbc546a" ++ "0d072b04b3564eea1b422273f548271a" ++ "0bb2316053fa76991955ebd63159434e" ++ "cebb4e466dae5a1073a6727627097a10" ++ "49e617d91d361094fa68f0ff77987130" ++ "305beaba2eda04df997b714d6c6f2c29" ++ "a6ad5cb4022b02709b"), ++ hexstr2bin("eead9d67890cbb22392336fea1851f38")} %% CipherTag + ]. + + rsa_plain() -> |