diff options
author | Todd Short <tshort@akamai.com> | 2016-12-16 17:00:43 -0500 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2017-01-24 15:40:37 +0100 |
commit | 52ad5b60e3a1fef12a1a5ea01527a90b8f92a34b (patch) | |
tree | 74ef6b469ac271f35b5573738ca00edf38cff89e | |
parent | 07afdf3c3ac97af4f2b4eec22a97f7230f8227e0 (diff) |
Add support for Poly1305 in EVP_PKEY
Add Poly1305 as a "signed" digest.
Reviewed-by: Andy Polyakov <appro@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2128)
-rw-r--r-- | crypto/asn1/standard_methods.h | 5 | ||||
-rw-r--r-- | crypto/evp/evp_err.c | 4 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 14 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 5 | ||||
-rw-r--r-- | crypto/include/internal/asn1_int.h | 2 | ||||
-rw-r--r-- | crypto/include/internal/evp_int.h | 1 | ||||
-rw-r--r-- | crypto/include/internal/poly1305.h | 4 | ||||
-rw-r--r-- | crypto/objects/obj_dat.h | 9 | ||||
-rw-r--r-- | crypto/objects/obj_mac.num | 1 | ||||
-rw-r--r-- | crypto/objects/objects.txt | 3 | ||||
-rw-r--r-- | crypto/poly1305/build.info | 2 | ||||
-rw-r--r-- | crypto/poly1305/poly1305_ameth.c | 67 | ||||
-rw-r--r-- | crypto/poly1305/poly1305_pmeth.c | 192 | ||||
-rw-r--r-- | doc/man3/EVP_DigestInit.pod | 9 | ||||
-rw-r--r-- | doc/man3/EVP_PKEY_CTX_ctrl.pod | 3 | ||||
-rw-r--r-- | include/openssl/evp.h | 11 | ||||
-rw-r--r-- | include/openssl/obj_mac.h | 4 | ||||
-rw-r--r-- | test/evp_test.c | 7 | ||||
-rw-r--r-- | test/evptests.txt | 255 | ||||
-rw-r--r-- | util/libcrypto.num | 1 |
20 files changed, 590 insertions, 9 deletions
diff --git a/crypto/asn1/standard_methods.h b/crypto/asn1/standard_methods.h index 322ba9787f..ca38b09fee 100644 --- a/crypto/asn1/standard_methods.h +++ b/crypto/asn1/standard_methods.h @@ -41,7 +41,10 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { &dhx_asn1_meth, #endif #ifndef OPENSSL_NO_EC - &ecx25519_asn1_meth + &ecx25519_asn1_meth, +#endif +#ifndef OPENSSL_NO_POLY1305 + &poly1305_asn1_meth, #endif }; diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 0331c2ae0c..2527df60dd 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -64,6 +64,7 @@ static ERR_STRING_DATA EVP_str_functs[] = { {ERR_FUNC(EVP_F_EVP_PKEY_GET0_DSA), "EVP_PKEY_get0_DSA"}, {ERR_FUNC(EVP_F_EVP_PKEY_GET0_EC_KEY), "EVP_PKEY_get0_EC_KEY"}, {ERR_FUNC(EVP_F_EVP_PKEY_GET0_HMAC), "EVP_PKEY_get0_hmac"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET0_POLY1305), "EVP_PKEY_get0_poly1305"}, {ERR_FUNC(EVP_F_EVP_PKEY_GET0_RSA), "EVP_PKEY_get0_RSA"}, {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"}, {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"}, @@ -114,6 +115,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = { {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"}, {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY), "expecting a dsa key"}, {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"}, + {ERR_REASON(EVP_R_EXPECTING_A_POLY1305_KEY), "expecting a poly1305 key"}, {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, {ERR_REASON(EVP_R_ILLEGAL_SCRYPT_PARAMETERS), "illegal scrypt parameters"}, diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 234d05f270..047e832637 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -249,6 +249,20 @@ const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len) return os->data; } +#ifndef OPENSSL_NO_POLY1305 +const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len) +{ + ASN1_OCTET_STRING *os = NULL; + if (pkey->type != EVP_PKEY_POLY1305) { + EVPerr(EVP_F_EVP_PKEY_GET0_POLY1305, EVP_R_EXPECTING_A_POLY1305_KEY); + return NULL; + } + os = EVP_PKEY_get0(pkey); + *len = os->length; + return os->data; +} +#endif + #ifndef OPENSSL_NO_RSA int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index e7845ed43b..66e1e08149 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -48,7 +48,10 @@ static const EVP_PKEY_METHOD *standard_methods[] = { #ifndef OPENSSL_NO_EC &ecx25519_pkey_meth, #endif - &hkdf_pkey_meth + &hkdf_pkey_meth, +#ifndef OPENSSL_NO_POLY1305 + &poly1305_pkey_meth, +#endif }; DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, diff --git a/crypto/include/internal/asn1_int.h b/crypto/include/internal/asn1_int.h index a5fdc0eb1d..554f067740 100644 --- a/crypto/include/internal/asn1_int.h +++ b/crypto/include/internal/asn1_int.h @@ -62,6 +62,8 @@ extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth; extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5]; extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; extern const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth; + extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2]; extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth; diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index 121523b64c..bb8a278ba7 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -87,6 +87,7 @@ extern const EVP_PKEY_METHOD rsa_pkey_meth; extern const EVP_PKEY_METHOD rsa_pss_pkey_meth; extern const EVP_PKEY_METHOD tls1_prf_pkey_meth; extern const EVP_PKEY_METHOD hkdf_pkey_meth; +extern const EVP_PKEY_METHOD poly1305_pkey_meth; struct evp_md_st { int type; diff --git a/crypto/include/internal/poly1305.h b/crypto/include/internal/poly1305.h index 1bc8716fca..5fef239d0f 100644 --- a/crypto/include/internal/poly1305.h +++ b/crypto/include/internal/poly1305.h @@ -9,7 +9,9 @@ #include <stddef.h> -#define POLY1305_BLOCK_SIZE 16 +#define POLY1305_BLOCK_SIZE 16 +#define POLY1305_DIGEST_SIZE 16 +#define POLY1305_KEY_SIZE 32 typedef struct poly1305_context POLY1305; diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index e1fc64f7c9..5171f56846 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -963,7 +963,7 @@ static const unsigned char so[6765] = { 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1C, /* [ 6753] OBJ_id_ct_xml */ }; -#define NUM_NID 1061 +#define NUM_NID 1062 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, @@ -2026,9 +2026,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"id-smime-ct-contentCollection", "id-smime-ct-contentCollection", NID_id_smime_ct_contentCollection, 11, &so[6731]}, {"id-smime-ct-authEnvelopedData", "id-smime-ct-authEnvelopedData", NID_id_smime_ct_authEnvelopedData, 11, &so[6742]}, {"id-ct-xml", "id-ct-xml", NID_id_ct_xml, 11, &so[6753]}, + {"Poly1305", "poly1305", NID_poly1305}, }; -#define NUM_SN 1052 +#define NUM_SN 1053 static const unsigned int sn_objs[NUM_SN] = { 364, /* "AD_DVCS" */ 419, /* "AES-128-CBC" */ @@ -2208,6 +2209,7 @@ static const unsigned int sn_objs[NUM_SN] = { 162, /* "PBMAC1" */ 127, /* "PKIX" */ 935, /* "PSPECIFIED" */ + 1061, /* "Poly1305" */ 98, /* "RC2-40-CBC" */ 166, /* "RC2-64-CBC" */ 37, /* "RC2-CBC" */ @@ -3084,7 +3086,7 @@ static const unsigned int sn_objs[NUM_SN] = { 160, /* "x509Crl" */ }; -#define NUM_LN 1052 +#define NUM_LN 1053 static const unsigned int ln_objs[NUM_LN] = { 363, /* "AD Time Stamping" */ 405, /* "ANSI X9.62" */ @@ -3866,6 +3868,7 @@ static const unsigned int ln_objs[NUM_LN] = { 22, /* "pkcs7-signedData" */ 151, /* "pkcs8ShroudedKeyBag" */ 47, /* "pkcs9" */ + 1061, /* "poly1305" */ 862, /* "postOfficeBox" */ 861, /* "postalAddress" */ 661, /* "postalCode" */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index a5995a513b..9aa490b670 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1058,3 +1058,4 @@ blake2s256 1057 id_smime_ct_contentCollection 1058 id_smime_ct_authEnvelopedData 1059 id_ct_xml 1060 +poly1305 1061 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index fc0781d1c9..09701af4a1 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -1482,4 +1482,5 @@ id-pkinit 5 : pkInitKDC : Signing KDC Response : AuthGOST12 : auth-gost12 : AuthSRP : auth-srp : AuthNULL : auth-null - +# NID for Poly1305 + : Poly1305 : poly1305 diff --git a/crypto/poly1305/build.info b/crypto/poly1305/build.info index 358fa82212..dae9aa467d 100644 --- a/crypto/poly1305/build.info +++ b/crypto/poly1305/build.info @@ -1,5 +1,7 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ + poly1305_pmeth.c \ + poly1305_ameth.c \ poly1305.c {- $target{poly1305_asm_src} -} GENERATE[poly1305-sparcv9.S]=asm/poly1305-sparcv9.pl $(PERLASM_SCHEME) diff --git a/crypto/poly1305/poly1305_ameth.c b/crypto/poly1305/poly1305_ameth.c new file mode 100644 index 0000000000..93c6bc0c33 --- /dev/null +++ b/crypto/poly1305/poly1305_ameth.c @@ -0,0 +1,67 @@ +/* + * Copyright 2007-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/evp.h> +#include "internal/asn1_int.h" +#include "internal/poly1305.h" +#include "poly1305_local.h" + +/* + * POLY1305 "ASN1" method. This is just here to indicate the maximum + * POLY1305 output length and to free up a POLY1305 key. + */ + +static int poly1305_size(const EVP_PKEY *pkey) +{ + return POLY1305_DIGEST_SIZE; +} + +static void poly1305_key_free(EVP_PKEY *pkey) +{ + ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey); + if (os != NULL) { + if (os->data != NULL) + OPENSSL_cleanse(os->data, os->length); + ASN1_OCTET_STRING_free(os); + } +} + +static int poly1305_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + /* nothing, (including ASN1_PKEY_CTRL_DEFAULT_MD_NID), is supported */ + return -2; +} + +static int poly1305_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b)); +} + +const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth = { + EVP_PKEY_POLY1305, + EVP_PKEY_POLY1305, + 0, + + "POLY1305", + "OpenSSL POLY1305 method", + + 0, 0, poly1305_pkey_public_cmp, 0, + + 0, 0, 0, + + poly1305_size, + 0, 0, + 0, 0, 0, 0, 0, 0, 0, + + poly1305_key_free, + poly1305_pkey_ctrl, + 0, 0 +}; diff --git a/crypto/poly1305/poly1305_pmeth.c b/crypto/poly1305/poly1305_pmeth.c new file mode 100644 index 0000000000..7bc6add681 --- /dev/null +++ b/crypto/poly1305/poly1305_pmeth.c @@ -0,0 +1,192 @@ +/* + * Copyright 2007-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include "internal/cryptlib.h" +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/evp.h> +#include "internal/poly1305.h" +#include "poly1305_local.h" +#include "internal/evp_int.h" + +/* POLY1305 pkey context structure */ + +typedef struct { + ASN1_OCTET_STRING ktmp; /* Temp storage for key */ + POLY1305 ctx; +} POLY1305_PKEY_CTX; + +static int pkey_poly1305_init(EVP_PKEY_CTX *ctx) +{ + POLY1305_PKEY_CTX *pctx; + + pctx = OPENSSL_zalloc(sizeof(*pctx)); + if (pctx == NULL) + return 0; + pctx->ktmp.type = V_ASN1_OCTET_STRING; + + EVP_PKEY_CTX_set_data(ctx, pctx); + EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0); + return 1; +} + +static void pkey_poly1305_cleanup(EVP_PKEY_CTX *ctx) +{ + POLY1305_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); + + if (pctx != NULL) { + OPENSSL_clear_free(pctx->ktmp.data, pctx->ktmp.length); + OPENSSL_clear_free(pctx, sizeof(*pctx)); + EVP_PKEY_CTX_set_data(ctx, NULL); + } +} + +static int pkey_poly1305_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + POLY1305_PKEY_CTX *sctx, *dctx; + + /* allocate memory for dst->data and a new POLY1305_CTX in dst->data->ctx */ + if (!pkey_poly1305_init(dst)) + return 0; + sctx = EVP_PKEY_CTX_get_data(src); + dctx = EVP_PKEY_CTX_get_data(dst); + if (ASN1_STRING_get0_data(&sctx->ktmp) != NULL && + !ASN1_STRING_copy(&dctx->ktmp, &sctx->ktmp)) { + /* cleanup and free the POLY1305_PKEY_CTX in dst->data */ + pkey_poly1305_cleanup(dst); + return 0; + } + memcpy(&dctx->ctx, &sctx->ctx, sizeof(POLY1305)); + return 1; +} + +static int pkey_poly1305_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + ASN1_OCTET_STRING *key; + POLY1305_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); + + if (ASN1_STRING_get0_data(&pctx->ktmp) == NULL) + return 0; + key = ASN1_OCTET_STRING_dup(&pctx->ktmp); + if (key == NULL) + return 0; + return EVP_PKEY_assign_POLY1305(pkey, key); +} + +static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + POLY1305_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)); + + Poly1305_Update(&pctx->ctx, data, count); + return 1; +} + +static int poly1305_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + POLY1305_PKEY_CTX *pctx = ctx->data; + ASN1_OCTET_STRING *key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; + + if (key->length != POLY1305_KEY_SIZE) + return 0; + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); + EVP_MD_CTX_set_update_fn(mctx, int_update); + Poly1305_Init(&pctx->ctx, key->data); + return 1; +} +static int poly1305_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx) +{ + POLY1305_PKEY_CTX *pctx = ctx->data; + + *siglen = POLY1305_DIGEST_SIZE; + if (sig != NULL) + Poly1305_Final(&pctx->ctx, sig); + return 1; +} + +static int pkey_poly1305_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + POLY1305_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx); + const unsigned char *key; + size_t len; + + switch (type) { + + case EVP_PKEY_CTRL_MD: + /* ignore */ + break; + + case EVP_PKEY_CTRL_SET_MAC_KEY: + case EVP_PKEY_CTRL_DIGESTINIT: + if (type == EVP_PKEY_CTRL_SET_MAC_KEY) { + /* user explicitly setting the key */ + key = p2; + len = p1; + } else { + /* user indirectly setting the key via EVP_DigestSignInit */ + key = EVP_PKEY_get0_poly1305(EVP_PKEY_CTX_get0_pkey(ctx), &len); + } + if (key == NULL || len != POLY1305_KEY_SIZE || + !ASN1_OCTET_STRING_set(&pctx->ktmp, key, len)) + return 0; + Poly1305_Init(&pctx->ctx, ASN1_STRING_get0_data(&pctx->ktmp)); + break; + + default: + return -2; + + } + return 1; +} + +static int pkey_poly1305_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (value == NULL) + return 0; + if (strcmp(type, "key") == 0) + return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); + if (strcmp(type, "hexkey") == 0) + return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); + return -2; +} + +const EVP_PKEY_METHOD poly1305_pkey_meth = { + EVP_PKEY_POLY1305, + EVP_PKEY_FLAG_SIGCTX_CUSTOM, /* we don't deal with a separate MD */ + pkey_poly1305_init, + pkey_poly1305_copy, + pkey_poly1305_cleanup, + + 0, 0, + + 0, + pkey_poly1305_keygen, + + 0, 0, + + 0, 0, + + 0, 0, + + poly1305_signctx_init, + poly1305_signctx, + + 0, 0, + + 0, 0, + + 0, 0, + + 0, 0, + + pkey_poly1305_ctrl, + pkey_poly1305_ctrl_str +}; diff --git a/doc/man3/EVP_DigestInit.pod b/doc/man3/EVP_DigestInit.pod index bb7ef7a28f..14f195a089 100644 --- a/doc/man3/EVP_DigestInit.pod +++ b/doc/man3/EVP_DigestInit.pod @@ -3,7 +3,7 @@ =head1 NAME EVP_MD_CTX_new, EVP_MD_CTX_reset, EVP_MD_CTX_free, EVP_MD_CTX_copy_ex, -EVP_DigestInit_ex, EVP_DigestUpdate, EVP_DigestFinal_ex, +EVP_MD_CTX_ctrl, EVP_DigestInit_ex, EVP_DigestUpdate, EVP_DigestFinal_ex, EVP_DigestInit, EVP_DigestFinal, EVP_MD_CTX_copy, EVP_MD_type, EVP_MD_pkey_type, EVP_MD_size, EVP_MD_block_size, EVP_MD_CTX_md, EVP_MD_CTX_size, EVP_MD_CTX_block_size, EVP_MD_CTX_type, EVP_md_null, EVP_md2, EVP_md5, EVP_sha1, @@ -18,6 +18,7 @@ EVP_get_digestbynid, EVP_get_digestbyobj - EVP digest routines EVP_MD_CTX *EVP_MD_CTX_new(void); int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); void EVP_MD_CTX_free(EVP_MD_CTX *ctx); + void EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void* p2); int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); @@ -73,6 +74,8 @@ to reuse an already existing context. EVP_MD_CTX_free() cleans up digest context B<ctx> and frees up the space allocated to it. +EVP_MD_CTX_ctrl() performs digest-specific control actions on context B<ctx>. + EVP_DigestInit_ex() sets up digest context B<ctx> to use a digest B<type> from ENGINE B<impl>. B<ctx> must be initialized before calling this function. B<type> will typically be supplied by a function such as EVP_sha1(). @@ -144,6 +147,8 @@ an ASN1_OBJECT structure respectively. EVP_DigestInit_ex(), EVP_DigestUpdate() and EVP_DigestFinal_ex() return 1 for success and 0 for failure. +EVP_MD_CTX_ctrl() returns 1 if successful or 0 for failure. + EVP_MD_CTX_copy_ex() returns 1 if successful or 0 for failure. EVP_MD_type(), EVP_MD_pkey_type() and EVP_MD_type() return the NID of the @@ -185,6 +190,8 @@ EVP_MD_CTX_size(), EVP_MD_CTX_block_size(), EVP_MD_CTX_type(), EVP_get_digestbynid() and EVP_get_digestbyobj() are defined as macros. +EVP_MD_CTX_ctrl() sends commands to message digests for additional configuration +or control. =head1 EXAMPLE diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod index 0732a05779..abe76c8089 100644 --- a/doc/man3/EVP_PKEY_CTX_ctrl.pod +++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod @@ -48,6 +48,9 @@ B<optype> is a mask indicating which operations the control can be applied to. The control command is indicated in B<cmd> and any additional arguments in B<p1> and B<p2>. +For B<cmd> = B<EVP_PKEY_CTRL_SET_MAC_KEY>, B<p1> is the length of the MAC key, +and B<p2> is MAC key. This is used by Poly1305, HMAC and CMAC. + Applications will not normally call EVP_PKEY_CTX_ctrl() directly but will instead call one of the algorithm specific macros below. diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 00c3a3dcf1..fda0713ce4 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -53,6 +53,7 @@ # define EVP_PKEY_CMAC NID_cmac # define EVP_PKEY_TLS1_PRF NID_tls1_prf # define EVP_PKEY_HKDF NID_hkdf +# define EVP_PKEY_POLY1305 NID_poly1305 #ifdef __cplusplus extern "C" { @@ -398,6 +399,11 @@ typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, (char *)(eckey)) # endif +# ifndef OPENSSL_NO_POLY1305 +# define EVP_PKEY_assign_POLY1305(pkey,polykey) EVP_PKEY_assign((pkey),EVP_PKEY_POLY1305,\ + (char *)(polykey)) +# endif + /* Add some extra combinations */ # define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) # define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) @@ -904,6 +910,9 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); void *EVP_PKEY_get0(const EVP_PKEY *pkey); const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len); +# ifndef OPENSSL_NO_POLY1305 +const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len); +# endif # ifndef OPENSSL_NO_RSA struct rsa_st; @@ -1500,6 +1509,7 @@ int ERR_load_EVP_strings(void); # define EVP_F_EVP_PKEY_GET0_DSA 120 # define EVP_F_EVP_PKEY_GET0_EC_KEY 131 # define EVP_F_EVP_PKEY_GET0_HMAC 183 +# define EVP_F_EVP_PKEY_GET0_POLY1305 169 # define EVP_F_EVP_PKEY_GET0_RSA 121 # define EVP_F_EVP_PKEY_KEYGEN 146 # define EVP_F_EVP_PKEY_KEYGEN_INIT 147 @@ -1544,6 +1554,7 @@ int ERR_load_EVP_strings(void); # define EVP_R_EXPECTING_A_DH_KEY 128 # define EVP_R_EXPECTING_A_DSA_KEY 129 # define EVP_R_EXPECTING_A_EC_KEY 142 +# define EVP_R_EXPECTING_A_POLY1305_KEY 164 # define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 # define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171 # define EVP_R_INITIALIZATION_ERROR 134 diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h index f97f3eaa17..faeb67526f 100644 --- a/include/openssl/obj_mac.h +++ b/include/openssl/obj_mac.h @@ -4575,3 +4575,7 @@ #define SN_auth_null "AuthNULL" #define LN_auth_null "auth-null" #define NID_auth_null 1053 + +#define SN_poly1305 "Poly1305" +#define LN_poly1305 "poly1305" +#define NID_poly1305 1061 diff --git a/test/evp_test.c b/test/evp_test.c index e5d7c91fe2..a4c3146888 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1125,6 +1125,13 @@ static int mac_test_init(struct evp_test *t, const char *alg) t->skip = 1; return 1; #endif + } else if (strcmp(alg, "Poly1305") == 0) { +#ifndef OPENSSL_NO_POLY1305 + type = EVP_PKEY_POLY1305; +#else + t->skip = 1; + return 1; +#endif } else return 0; diff --git a/test/evptests.txt b/test/evptests.txt index 91830bcd7b..5dde7a3c89 100644 --- a/test/evptests.txt +++ b/test/evptests.txt @@ -3909,3 +3909,258 @@ Verify=Alice-25519 Result = KEYOP_INIT_ERROR Function = EVP_PKEY_verify_init Reason = operation not supported for this keytype + +# Poly1305 Tests From RFC 7539 + +MAC = Poly1305 +Key = 0000000000000000000000000000000000000000000000000000000000000000 +Input = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +Output = 00000000000000000000000000000000 + +MAC = Poly1305 +Key = 0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e +Input = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f +Output = 36e5f6b5c5e06070f0efca96227a863e + +MAC = Poly1305 +Key = 36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000 +Input = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f +Output = f3477e7cd95417af89a6b8794c310cf0 + +MAC = Poly1305 +Key = 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0 +Input = 2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e +Output = 4541669a7eaaee61e708dc7cbcc5eb62 + +# If one uses 130-bit partial reduction, does the code handle the case where partially reduced final result is not fully reduced? +MAC = Poly1305 +Key = 0200000000000000000000000000000000000000000000000000000000000000 +Input = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +Output = 03000000000000000000000000000000 + +# What happens if addition of s overflows modulo 2^128? +MAC = Poly1305 +Key = 02000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +Input = 02000000000000000000000000000000 +Output = 03000000000000000000000000000000 + +# What happens if data limb is all ones and there is carry from lower limb? +MAC = Poly1305 +Key = 0100000000000000000000000000000000000000000000000000000000000000 +Input = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11000000000000000000000000000000 +Output = 05000000000000000000000000000000 + +# What happens if final result from polynomial part is exactly 2^130-5? +MAC = Poly1305 +Key = 0100000000000000000000000000000000000000000000000000000000000000 +Input = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE01010101010101010101010101010101 +Output = 00000000000000000000000000000000 + +# What happens if final result from polynomial part is exactly 2^130-6? +MAC = Poly1305 +Key = 0200000000000000000000000000000000000000000000000000000000000000 +Input = FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +Output = FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + +# Taken from poly1305_internal_test.c +# More RFC7539 + +MAC = Poly1305 +Input = 43727970746f6772617068696320466f72756d2052657365617263682047726f7570 +Key = 85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b +Output = a8061dc1305136c6c22b8baf0c0127a9 + +# test vectors from "The Poly1305-AES message-authentication code" + +MAC = Poly1305 +Input = f3f6 +Key = 851fc40c3467ac0be05cc20404f3f700580b3b0f9447bb1e69d095b5928b6dbc +Output = f4c633c3044fc145f84f335cb81953de + +# No input? +# MAC = Poly1305 +# Input = +# Key = a0f3080000f46400d0c7e9076c834403dd3fab2251f11ac759f0887129cc2ee7 +# Output = dd3fab2251f11ac759f0887129cc2ee7 + +MAC = Poly1305 +Input = 663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136 +Key = 48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef +Output = 0ee1c16bb73f0f4fd19881753c01cdbe + +MAC = Poly1305 +Input = ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9 +Key = 12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57 +Output = 5154ad0d2cb26e01274fc51148491f1b + +# self-generated vectors exercise "significant" length such that* are handled by different code paths + +MAC = Poly1305 +Input = ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af +Key = 12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57 +Output = 812059a5da198637cac7c4a631bee466 + +MAC = Poly1305 +Input = ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0990c62e48b8018b2c3e4a0fa3134cb67 +Key = 12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57 +Output = 5b88d7f6228b11e2e28579a5c0c1f761 + +MAC = Poly1305 +Input = ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136 +Key = 12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57 +Output = bbb613b2b6d753ba07395b916aaece15 + +MAC = Poly1305 +Input = ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef663cea190ffb83d89593f3f476b6bc24 +Key = 12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57 +Output = c794d7057d1778c4bbee0a39b3d97342 + +MAC = Poly1305 +Input = ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136 +Key = 12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57 +Output = ffbcb9b371423152d7fca5ad042fbaa9 + +MAC = Poly1305 +Input = ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136812059a5da198637cac7c4a631bee466 +Key = 12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57 +Output = 069ed6b8ef0f207b3e243bb1019fe632 + +MAC = Poly1305 +Input = ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761 +Key = 12976a08c4426d0ce8a82407c4f4820780f8c20aa71202d1e29179cbcb555a57 +Output = cca339d9a45fa2368c2c68b3a4179133 |