Latest update.

This commit is contained in:
2019-09-21 00:43:47 +09:00
parent 2e57f602ae
commit 62515c7d8d
1131 changed files with 47556 additions and 24957 deletions
+160 -35
View File
@@ -7,8 +7,12 @@
* https://www.openssl.org/source/license.html
*/
#include <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <openssl/params.h>
#include <openssl/core_names.h>
#include "internal/evp_int.h"
#include "evp_locl.h"
@@ -40,18 +44,21 @@ typedef struct {
} raw_data;
} MAC_PKEY_CTX;
static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
static int pkey_mac_init(EVP_PKEY_CTX *ctx)
{
MAC_PKEY_CTX *hctx;
/* We're being smart and using the same base NIDs for PKEY and for MAC */
int nid = ctx->pmeth->pkey_id;
EVP_MAC *mac = EVP_MAC_fetch(NULL, OBJ_nid2sn(nid), NULL);
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
return 0;
}
/* We're being smart and using the same base NIDs for PKEY and for MAC */
hctx->ctx = EVP_MAC_CTX_new_id(nid);
hctx->ctx = EVP_MAC_CTX_new(mac);
if (hctx->ctx == NULL) {
OPENSSL_free(hctx);
return 0;
@@ -64,14 +71,13 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx)
hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
}
pkey_mac_cleanup(ctx);
EVP_PKEY_CTX_set_data(ctx, hctx);
ctx->keygen_info_count = 0;
return 1;
}
static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
{
MAC_PKEY_CTX *sctx, *dctx;
@@ -93,6 +99,17 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
if (dctx->ctx == NULL)
goto err;
/*
* Normally, nothing special would be done with the MAC method. In
* this particular case, though, the MAC method was fetched internally
* by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed
* via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX
* fetches the MAC method anew in this case. Therefore, its reference
* count must be adjusted here.
*/
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx)))
goto err;
dctx->type = sctx->type;
switch (dctx->type) {
@@ -117,9 +134,16 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
/*
* For the exact same reasons the MAC reference count is incremented
* in pkey_mac_copy() above, it must be explicitly freed here.
*/
MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
if (hctx != NULL) {
EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
switch (hctx->type) {
case MAC_TYPE_RAW:
OPENSSL_clear_free(hctx->raw_data.ktmp.data,
@@ -127,6 +151,7 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
break;
}
EVP_MAC_CTX_free(hctx->ctx);
EVP_MAC_free(mac);
OPENSSL_free(hctx);
EVP_PKEY_CTX_set_data(ctx, NULL);
}
@@ -156,6 +181,8 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
if (cmkey == NULL)
return 0;
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
return 0;
EVP_PKEY_assign(pkey, nid, cmkey);
}
break;
@@ -194,25 +221,34 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
&& (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
if (set_key) {
if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))
!= EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx)))
if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
return 0;
key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
if (key == NULL)
return 0;
}
/* Some MACs don't support this control... that's fine */
EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS,
EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
EVP_MD_CTX_set_update_fn(mctx, int_update);
if (set_key)
rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data,
key->length);
return rv > 0;
/* Some MACs don't support this control... that's fine */
{
OSSL_PARAM params[3];
size_t params_n = 0;
int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT);
/* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */
params[params_n++] =
OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags);
if (set_key)
params[params_n++] =
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
key->data, key->length);
params[params_n++] = OSSL_PARAM_construct_end();
rv = EVP_MAC_CTX_set_params(hctx->ctx, params);
}
return rv;
}
static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
@@ -220,7 +256,7 @@ static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
return EVP_MAC_final(hctx->ctx, sig, siglen);
return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx));
}
static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
@@ -235,14 +271,24 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return -2; /* The raw types don't support ciphers */
case MAC_TYPE_MAC:
{
int rv;
OSSL_PARAM params[3];
size_t params_n = 0;
char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2));
#ifndef OPENSSL_NO_ENGINE
char *engineid = (char *)ENGINE_get_id(ctx->engine);
if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
ctx->engine)) <= 0
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_CIPHER,
p2)) <= 0
|| !(rv = EVP_MAC_init(hctx->ctx)))
return rv;
params[params_n++] =
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
engineid, 0);
#endif
params[params_n++] =
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
ciphname, 0);
params[params_n] = OSSL_PARAM_construct_end();
if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
|| !EVP_MAC_init(hctx->ctx))
return 0;
}
break;
default:
@@ -276,8 +322,40 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
break;
case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
return EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_SIZE, (size_t)p1);
{
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
size_t size = (size_t)p1;
size_t verify = 0;
/*
* We verify that the length is actually set by getting back
* the same parameter and checking that it matches what we
* tried to set.
* TODO(3.0) when we have a more direct mechanism to check if
* a parameter was used, we must refactor this to use that.
*/
params[0] =
OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
return 0;
params[0] =
OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify);
if (!EVP_MAC_CTX_get_params(hctx->ctx, params))
return 0;
/*
* Since EVP_MAC_CTX_{get,set}_params() returned successfully,
* we can only assume that the size was ignored, i.e. this
* control is unsupported.
*/
if (verify != size)
return -2;
}
break;
case EVP_PKEY_CTRL_SET_MAC_KEY:
switch (hctx->type) {
case MAC_TYPE_RAW:
@@ -287,8 +365,17 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return 0;
break;
case MAC_TYPE_MAC:
if (EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1) <= 0)
return 0;
{
OSSL_PARAM params[2];
size_t params_n = 0;
params[params_n++] =
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
p2, p1);
params[params_n] = OSSL_PARAM_construct_end();
return EVP_MAC_CTX_set_params(hctx->ctx, params);
}
break;
default:
/* This should be dead code */
@@ -303,17 +390,31 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
if (!EVP_MAC_init(hctx->ctx))
return 0;
{
int rv;
ASN1_OCTET_STRING *key =
(ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
OSSL_PARAM params[4];
size_t params_n = 0;
char *mdname =
(char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md));
#ifndef OPENSSL_NO_ENGINE
char *engineid = ctx->engine == NULL
? NULL : (char *)ENGINE_get_id(ctx->engine);
if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
ctx->engine)) <= 0
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_MD,
hctx->raw_data.md)) <= 0
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY,
key->data, key->length)) <= 0)
return rv;
if (engineid != NULL) {
params[params_n++] =
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
engineid, 0);
}
#endif
params[params_n++] =
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
mdname, 0);
params[params_n++] =
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
key->data, key->length);
params[params_n] = OSSL_PARAM_construct_end();
return EVP_MAC_CTX_set_params(hctx->ctx, params);
}
break;
case MAC_TYPE_MAC:
@@ -335,8 +436,32 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
const EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
OSSL_PARAM params[2];
int ok = 0;
return EVP_MAC_ctrl_str(hctx->ctx, type, value);
/*
* Translation of some control names that are equivalent to a single
* parameter name.
*
* "md" and "digest" are the same thing, we use the single "digest"
*
* "digestsize" was a setting control in siphash, but naming wise,
* it's really the same as "size".
*/
if (strcmp(type, "md") == 0)
type = OSSL_MAC_PARAM_DIGEST;
else if (strcmp(type, "digestsize") == 0)
type = OSSL_MAC_PARAM_SIZE;
if (!OSSL_PARAM_allocate_from_text(&params[0],
EVP_MAC_CTX_settable_params(mac),
type, value, strlen(value) + 1))
return 0;
params[1] = OSSL_PARAM_construct_end();
ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
OPENSSL_free(params[0].data);
return ok;
}
const EVP_PKEY_METHOD cmac_pkey_meth = {