Prepare to provide EVP_PKEY_new_CMAC_key()
authortb <tb@openbsd.org>
Mon, 29 Mar 2021 15:57:23 +0000 (15:57 +0000)
committertb <tb@openbsd.org>
Mon, 29 Mar 2021 15:57:23 +0000 (15:57 +0000)
sebastia ran into this when attempting to update security/hcxtools.
This will be tested via wycheproof.go once the symbol is public.

ok jsing, tested by sebastia

lib/libcrypto/evp/evp.h
lib/libcrypto/evp/evp_err.c
lib/libcrypto/evp/m_sigver.c
lib/libcrypto/evp/p_lib.c

index f1fe8a1..ca51429 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp.h,v 1.79 2020/04/27 19:31:02 tb Exp $ */
+/* $OpenBSD: evp.h,v 1.80 2021/03/29 15:57:23 tb Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -1149,6 +1149,10 @@ void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
 
 EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key,
     int keylen);
+#if defined(LIBRESSL_INTERNAL)
+EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
+    size_t len, const EVP_CIPHER *cipher);
+#endif
 
 void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
 void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
@@ -1512,6 +1516,9 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_INVALID_OPERATION                                 148
 #define EVP_R_IV_TOO_LARGE                              102
 #define EVP_R_KEYGEN_FAILURE                            120
+#if defined(LIBRESSL_INTERNAL)
+#define EVP_R_KEY_SETUP_FAILED                          180
+#endif
 #define EVP_R_MESSAGE_DIGEST_IS_NULL                    159
 #define EVP_R_METHOD_NOT_SUPPORTED                      144
 #define EVP_R_MISSING_PARAMETERS                        103
index 2494cf5..07ece82 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp_err.c,v 1.26 2020/04/27 19:31:02 tb Exp $ */
+/* $OpenBSD: evp_err.c,v 1.27 2021/03/29 15:57:23 tb Exp $ */
 /* ====================================================================
  * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
  *
@@ -116,6 +116,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = {
        {ERR_REASON(EVP_R_INVALID_OPERATION)     , "invalid operation"},
        {ERR_REASON(EVP_R_IV_TOO_LARGE)          , "iv too large"},
        {ERR_REASON(EVP_R_KEYGEN_FAILURE)        , "keygen failure"},
+       {ERR_REASON(EVP_R_KEY_SETUP_FAILED)      , "key setup failed"},
        {ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"},
        {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED)  , "method not supported"},
        {ERR_REASON(EVP_R_MISSING_PARAMETERS)    , "missing parameters"},
index 9e313c3..f7dcaff 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: m_sigver.c,v 1.7 2018/05/13 06:35:10 tb Exp $ */
+/* $OpenBSD: m_sigver.c,v 1.8 2021/03/29 15:57:23 tb Exp $ */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2006.
  */
@@ -74,15 +74,17 @@ do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
        if (ctx->pctx == NULL)
                return 0;
 
-       if (type == NULL) {
-               int def_nid;
-               if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
-                       type = EVP_get_digestbynid(def_nid);
-       }
+       if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
+               if (type == NULL) {
+                       int def_nid;
+                       if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+                               type = EVP_get_digestbynid(def_nid);
+               }
 
-       if (type == NULL) {
-               EVPerror(EVP_R_NO_DEFAULT_DIGEST);
-               return 0;
+               if (type == NULL) {
+                       EVPerror(EVP_R_NO_DEFAULT_DIGEST);
+                       return 0;
+               }
        }
 
        if (ver) {
@@ -105,6 +107,8 @@ do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
                return 0;
        if (pctx)
                *pctx = ctx->pctx;
+       if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
+               return 1;
        if (!EVP_DigestInit_ex(ctx, type, e))
                return 0;
        return 1;
@@ -127,7 +131,24 @@ EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
 int
 EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
 {
-       int sctx, r = 0;
+       EVP_PKEY_CTX *pctx = ctx->pctx;
+       int sctx;
+       int r = 0;
+
+       if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
+               EVP_PKEY_CTX *dctx;
+
+               if (sigret == NULL)
+                       return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
+
+               /* XXX - support EVP_MD_CTX_FLAG_FINALISE? */
+               if ((dctx = EVP_PKEY_CTX_dup(ctx->pctx)) == NULL)
+                       return 0;
+               r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
+               EVP_PKEY_CTX_free(dctx);
+
+               return r;
+       }
 
        if (ctx->pctx->pmeth->signctx)
                sctx = 1;
index 13a9d65..9577b10 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: p_lib.c,v 1.25 2019/03/17 18:17:45 tb Exp $ */
+/* $OpenBSD: p_lib.c,v 1.26 2021/03/29 15:57:23 tb Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -61,6 +61,7 @@
 #include <openssl/opensslconf.h>
 
 #include <openssl/bn.h>
+#include <openssl/cmac.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/objects.h>
@@ -216,10 +217,14 @@ EVP_PKEY_up_ref(EVP_PKEY *pkey)
  */
 
 static int
-pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
+pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, int len)
 {
        const EVP_PKEY_ASN1_METHOD *ameth;
-       ENGINE *e = NULL;
+       ENGINE **eptr = NULL;
+
+       if (e == NULL)
+               eptr = &e;
+
        if (pkey) {
                if (pkey->pkey.ptr)
                        EVP_PKEY_free_it(pkey);
@@ -234,11 +239,11 @@ pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
 #endif
        }
        if (str)
-               ameth = EVP_PKEY_asn1_find_str(&e, str, len);
+               ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
        else
-               ameth = EVP_PKEY_asn1_find(&e, type);
+               ameth = EVP_PKEY_asn1_find(eptr, type);
 #ifndef OPENSSL_NO_ENGINE
-       if (pkey == NULL)
+       if (pkey == NULL && eptr != NULL)
                ENGINE_finish(e);
 #endif
        if (!ameth) {
@@ -258,13 +263,43 @@ pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
 int
 EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
 {
-       return pkey_set_type(pkey, type, NULL, -1);
+       return pkey_set_type(pkey, NULL, type, NULL, -1);
+}
+
+EVP_PKEY *
+EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len,
+    const EVP_CIPHER *cipher)
+{
+       EVP_PKEY *ret = NULL;
+       CMAC_CTX *cmctx = NULL;
+
+       if ((ret = EVP_PKEY_new()) == NULL)
+               goto err;
+       if ((cmctx = CMAC_CTX_new()) == NULL)
+               goto err;
+
+       if (!pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1))
+               goto err;
+
+       if (!CMAC_Init(cmctx, priv, len, cipher, e)) {
+               EVPerror(EVP_R_KEY_SETUP_FAILED);
+               goto err;
+       }
+
+       ret->pkey.ptr = (char *)cmctx;
+
+       return ret;
+
+ err:
+       EVP_PKEY_free(ret);
+       CMAC_CTX_free(cmctx);
+       return NULL;
 }
 
 int
 EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
 {
-       return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
+       return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
 }
 
 int