Now that the all the legacy PKEY MAC bridge code has been moved to the providers we no longer need the old bridge and it can be removed. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/12637)master
parent
a540ef90f5
commit
2cf765e5a2
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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
|
||||
*/
|
||||
|
||||
/*
|
||||
* CMAC low level APIs are deprecated for public use, but still ok for internal
|
||||
* use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "crypto/asn1.h"
|
||||
|
||||
/*
|
||||
* CMAC "ASN1" method. This is just here to indicate the maximum CMAC output
|
||||
* length and to free up a CMAC key.
|
||||
*/
|
||||
|
||||
static int cmac_size(const EVP_PKEY *pkey)
|
||||
{
|
||||
return EVP_MAX_BLOCK_LENGTH;
|
||||
}
|
||||
|
||||
static void cmac_key_free(EVP_PKEY *pkey)
|
||||
{
|
||||
EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey);
|
||||
EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_CTX_mac(cmctx);
|
||||
|
||||
EVP_MAC_CTX_free(cmctx);
|
||||
EVP_MAC_free(mac);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = {
|
||||
EVP_PKEY_CMAC,
|
||||
EVP_PKEY_CMAC,
|
||||
0,
|
||||
|
||||
"CMAC",
|
||||
"OpenSSL CMAC method",
|
||||
|
||||
0, 0, 0, 0,
|
||||
|
||||
0, 0, 0,
|
||||
|
||||
cmac_size,
|
||||
0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
cmac_key_free,
|
||||
0,
|
||||
0, 0
|
||||
};
|
@ -1,696 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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
|
||||
*/
|
||||
|
||||
/* We need to use some engine deprecated APIs */
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
|
||||
#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 "crypto/evp.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
/* MAC PKEY context structure */
|
||||
|
||||
typedef struct {
|
||||
EVP_MAC_CTX *ctx;
|
||||
|
||||
/*
|
||||
* We know of two MAC types:
|
||||
*
|
||||
* 1. those who take a secret in raw form, i.e. raw data as a
|
||||
* ASN1_OCTET_STRING embedded in a EVP_PKEY. So far, that's
|
||||
* all of them but CMAC.
|
||||
* 2. those who take a secret with associated cipher in very generic
|
||||
* form, i.e. a complete EVP_MAC_CTX embedded in a PKEY. So far,
|
||||
* only CMAC does this.
|
||||
*
|
||||
* (one might wonder why the second form isn't used for all)
|
||||
*/
|
||||
#define MAC_TYPE_RAW 1 /* HMAC like MAC type (all but CMAC so far) */
|
||||
#define MAC_TYPE_MAC 2 /* CMAC like MAC type (only CMAC known so far) */
|
||||
int type;
|
||||
|
||||
/* The following is only used for MAC_TYPE_RAW implementations */
|
||||
struct {
|
||||
const EVP_MD *md; /* temp storage of MD */
|
||||
ASN1_OCTET_STRING ktmp; /* temp storage for key */
|
||||
} 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;
|
||||
|
||||
ERR_set_mark();
|
||||
mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
|
||||
ERR_pop_to_mark();
|
||||
|
||||
/*
|
||||
* mac == NULL may actually be ok in some situations. In an
|
||||
* EVP_PKEY_new_mac_key() call a temporary EVP_PKEY_CTX is created with
|
||||
* default libctx. We don't actually need the underlying MAC to be present
|
||||
* to successfully set the key in that case. The resulting EVP_PKEY could
|
||||
* then be used in some other libctx where the MAC *is* present
|
||||
*/
|
||||
|
||||
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
|
||||
EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mac != NULL) {
|
||||
hctx->ctx = EVP_MAC_CTX_new(mac);
|
||||
if (hctx->ctx == NULL) {
|
||||
OPENSSL_free(hctx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (nid == EVP_PKEY_CMAC) {
|
||||
hctx->type = MAC_TYPE_MAC;
|
||||
} else {
|
||||
hctx->type = MAC_TYPE_RAW;
|
||||
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 int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
|
||||
{
|
||||
MAC_PKEY_CTX *sctx, *dctx;
|
||||
|
||||
sctx = EVP_PKEY_CTX_get_data(src);
|
||||
|
||||
if (sctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sctx->ctx->data == NULL)
|
||||
return 0;
|
||||
|
||||
dctx = OPENSSL_zalloc(sizeof(*dctx));
|
||||
if (dctx == NULL) {
|
||||
EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_set_data(dst, dctx);
|
||||
dst->keygen_info_count = 0;
|
||||
|
||||
dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx);
|
||||
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) {
|
||||
case MAC_TYPE_RAW:
|
||||
dctx->raw_data.md = sctx->raw_data.md;
|
||||
if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL &&
|
||||
!ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp))
|
||||
goto err;
|
||||
break;
|
||||
case MAC_TYPE_MAC:
|
||||
/* Nothing more to do */
|
||||
break;
|
||||
default:
|
||||
/* This should be dead code */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
pkey_mac_cleanup(dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pkey_mac_cleanup(EVP_PKEY_CTX *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 = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL;
|
||||
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
OPENSSL_clear_free(hctx->raw_data.ktmp.data,
|
||||
hctx->raw_data.ktmp.length);
|
||||
break;
|
||||
}
|
||||
EVP_MAC_CTX_free(hctx->ctx);
|
||||
EVP_MAC_free(mac);
|
||||
OPENSSL_free(hctx);
|
||||
EVP_PKEY_CTX_set_data(ctx, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
|
||||
int nid = ctx->pmeth->pkey_id;
|
||||
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
{
|
||||
ASN1_OCTET_STRING *hkey = NULL;
|
||||
|
||||
if (!hctx->raw_data.ktmp.data)
|
||||
return 0;
|
||||
hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp);
|
||||
if (!hkey)
|
||||
return 0;
|
||||
EVP_PKEY_assign(pkey, nid, hkey);
|
||||
}
|
||||
break;
|
||||
case MAC_TYPE_MAC:
|
||||
{
|
||||
EVP_MAC_CTX *cmkey;
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmkey = EVP_MAC_CTX_dup(hctx->ctx);
|
||||
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;
|
||||
default:
|
||||
/* This should be dead code */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
|
||||
|
||||
if (!EVP_MAC_update(hctx->ctx, data, count))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||
{
|
||||
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
|
||||
ASN1_OCTET_STRING *key = NULL;
|
||||
int rv = 1;
|
||||
/*
|
||||
* For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
|
||||
* gets the key passed as an ASN.1 OCTET STRING, we set the key here,
|
||||
* as this may be only time it's set during a DigestSign.
|
||||
*
|
||||
* MACs that pass around the key in form of EVP_MAC_CTX are setting
|
||||
* the key through other mechanisms. (this is only CMAC for now)
|
||||
*/
|
||||
int set_key =
|
||||
hctx->type == MAC_TYPE_RAW
|
||||
&& (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (set_key) {
|
||||
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;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
|
||||
EVP_MD_CTX_set_update_fn(mctx, int_update);
|
||||
|
||||
/* 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,
|
||||
size_t *siglen, EVP_MD_CTX *mctx)
|
||||
{
|
||||
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
|
||||
|
||||
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)
|
||||
{
|
||||
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
|
||||
|
||||
switch (type) {
|
||||
|
||||
case EVP_PKEY_CTRL_CIPHER:
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
return -2; /* The raw types don't support ciphers */
|
||||
case MAC_TYPE_MAC:
|
||||
{
|
||||
OSSL_PARAM params[3];
|
||||
size_t params_n = 0;
|
||||
char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2));
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (ctx->engine != NULL) {
|
||||
char *engid = (char *)ENGINE_get_id(ctx->engine);
|
||||
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_utf8_string("engine", engid, 0);
|
||||
}
|
||||
#endif
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
|
||||
ciphname, 0);
|
||||
params[params_n] = OSSL_PARAM_construct_end();
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/*
|
||||
* This actually means the fetch failed during the init call
|
||||
*/
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
|
||||
|| !EVP_MAC_init(hctx->ctx))
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* This should be dead code */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
hctx->raw_data.md = p2;
|
||||
break;
|
||||
case MAC_TYPE_MAC: {
|
||||
EVP_MAC_CTX *new_mac_ctx;
|
||||
|
||||
if (ctx->pkey == NULL)
|
||||
return 0;
|
||||
new_mac_ctx = EVP_MAC_CTX_dup(ctx->pkey->pkey.ptr);
|
||||
if (new_mac_ctx == NULL)
|
||||
return 0;
|
||||
EVP_MAC_CTX_free(hctx->ctx);
|
||||
hctx->ctx = new_mac_ctx;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* This should be dead code */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
|
||||
{
|
||||
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 (hctx->ctx == NULL) {
|
||||
/*
|
||||
* This actually means the fetch failed during the init call
|
||||
*/
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_{get,set}_ctx_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:
|
||||
if ((!p2 && p1 > 0) || (p1 < -1))
|
||||
return 0;
|
||||
if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1))
|
||||
return 0;
|
||||
break;
|
||||
case MAC_TYPE_MAC:
|
||||
{
|
||||
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();
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/*
|
||||
* This actually means the fetch failed during the init call
|
||||
*/
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* This should be dead code */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVP_PKEY_CTRL_DIGESTINIT:
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
if (hctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ensure that we have attached the implementation */
|
||||
if (!EVP_MAC_init(hctx->ctx))
|
||||
return 0;
|
||||
{
|
||||
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
|
||||
if (ctx->engine != NULL) {
|
||||
char *engid = (char *)ENGINE_get_id(ctx->engine);
|
||||
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_utf8_string("engine", engid, 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:
|
||||
return -2; /* The mac types don't support ciphers */
|
||||
default:
|
||||
/* This should be dead code */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
OSSL_PARAM params[2];
|
||||
int ok = 0;
|
||||
|
||||
if (hctx == NULL) {
|
||||
EVPerr(0, EVP_R_NULL_MAC_PKEY_CTX);
|
||||
return 0;
|
||||
}
|
||||
if (hctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
mac = EVP_MAC_CTX_mac(hctx->ctx);
|
||||
|
||||
/*
|
||||
* 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(¶ms[0],
|
||||
EVP_MAC_settable_ctx_params(mac),
|
||||
type, value, strlen(value) + 1, NULL))
|
||||
return 0;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
OPENSSL_free(params[0].data);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static const EVP_PKEY_METHOD cmac_pkey_meth = {
|
||||
EVP_PKEY_CMAC,
|
||||
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
|
||||
pkey_mac_init,
|
||||
pkey_mac_copy,
|
||||
pkey_mac_cleanup,
|
||||
|
||||
0, 0,
|
||||
|
||||
0,
|
||||
pkey_mac_keygen,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_signctx_init,
|
||||
pkey_mac_signctx,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_ctrl,
|
||||
pkey_mac_ctrl_str
|
||||
};
|
||||
|
||||
const EVP_PKEY_METHOD *cmac_pkey_method(void)
|
||||
{
|
||||
return &cmac_pkey_meth;
|
||||
}
|
||||
|
||||
static const EVP_PKEY_METHOD hmac_pkey_meth = {
|
||||
EVP_PKEY_HMAC,
|
||||
0,
|
||||
pkey_mac_init,
|
||||
pkey_mac_copy,
|
||||
pkey_mac_cleanup,
|
||||
|
||||
0, 0,
|
||||
|
||||
0,
|
||||
pkey_mac_keygen,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_signctx_init,
|
||||
pkey_mac_signctx,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_ctrl,
|
||||
pkey_mac_ctrl_str
|
||||
};
|
||||
|
||||
const EVP_PKEY_METHOD *hmac_pkey_method(void)
|
||||
{
|
||||
return &hmac_pkey_meth;
|
||||
}
|
||||
|
||||
static const EVP_PKEY_METHOD siphash_pkey_meth = {
|
||||
EVP_PKEY_SIPHASH,
|
||||
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
|
||||
pkey_mac_init,
|
||||
pkey_mac_copy,
|
||||
pkey_mac_cleanup,
|
||||
|
||||
0, 0,
|
||||
|
||||
0,
|
||||
pkey_mac_keygen,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_signctx_init,
|
||||
pkey_mac_signctx,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_ctrl,
|
||||
pkey_mac_ctrl_str
|
||||
};
|
||||
|
||||
const EVP_PKEY_METHOD *siphash_pkey_method(void)
|
||||
{
|
||||
return &siphash_pkey_meth;
|
||||
}
|
||||
|
||||
static const EVP_PKEY_METHOD poly1305_pkey_meth = {
|
||||
EVP_PKEY_POLY1305,
|
||||
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
|
||||
pkey_mac_init,
|
||||
pkey_mac_copy,
|
||||
pkey_mac_cleanup,
|
||||
|
||||
0, 0,
|
||||
|
||||
0,
|
||||
pkey_mac_keygen,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_signctx_init,
|
||||
pkey_mac_signctx,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_ctrl,
|
||||
pkey_mac_ctrl_str
|
||||
};
|
||||
|
||||
const EVP_PKEY_METHOD *poly1305_pkey_method(void)
|
||||
{
|
||||
return &poly1305_pkey_meth;
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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
|
||||
*/
|
||||
|
||||
/*
|
||||
* HMAC low level APIs are deprecated for public use, but still ok for internal
|
||||
* use.
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
|
||||
/*
|
||||
* HMAC "ASN1" method. This is just here to indicate the maximum HMAC output
|
||||
* length and to free up an HMAC key.
|
||||
*/
|
||||
|
||||
static int hmac_size(const EVP_PKEY *pkey)
|
||||
{
|
||||
return EVP_MAX_MD_SIZE;
|
||||
}
|
||||
|
||||
static void hmac_key_free(EVP_PKEY *pkey)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey);
|
||||
if (os) {
|
||||
if (os->data)
|
||||
OPENSSL_cleanse(os->data, os->length);
|
||||
ASN1_OCTET_STRING_free(os);
|
||||
}
|
||||
}
|
||||
|
||||
static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
{
|
||||
switch (op) {
|
||||
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
|
||||
*(int *)arg2 = NID_sha256;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
static int hmac_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b));
|
||||
}
|
||||
|
||||
static int hmac_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
|
||||
size_t len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os;
|
||||
|
||||
if (pkey->pkey.ptr != NULL)
|
||||
return 0;
|
||||
|
||||
os = ASN1_OCTET_STRING_new();
|
||||
if (os == NULL)
|
||||
return 0;
|
||||
|
||||
|
||||
if (!ASN1_OCTET_STRING_set(os, priv, len)) {
|
||||
ASN1_OCTET_STRING_free(os);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey->pkey.ptr = os;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int hmac_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
|
||||
|
||||
if (priv == NULL) {
|
||||
*len = ASN1_STRING_length(os);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (os == NULL || *len < (size_t)ASN1_STRING_length(os))
|
||||
return 0;
|
||||
|
||||
*len = ASN1_STRING_length(os);
|
||||
memcpy(priv, ASN1_STRING_get0_data(os), *len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
|
||||
EVP_PKEY_HMAC,
|
||||
EVP_PKEY_HMAC,
|
||||
0,
|
||||
|
||||
"HMAC",
|
||||
"OpenSSL HMAC method",
|
||||
|
||||
0, 0, hmac_pkey_public_cmp, 0,
|
||||
|
||||
0, 0, 0,
|
||||
|
||||
hmac_size,
|
||||
0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
hmac_key_free,
|
||||
hmac_pkey_ctrl,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
hmac_set_priv_key,
|
||||
NULL,
|
||||
hmac_get_priv_key,
|
||||
NULL,
|
||||
};
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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 "crypto/asn1.h"
|
||||
#include "crypto/poly1305.h"
|
||||
#include "crypto/evp.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));
|
||||
}
|
||||
|
||||
static int poly1305_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
|
||||
size_t len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os;
|
||||
|
||||
if (pkey->pkey.ptr != NULL || len != POLY1305_KEY_SIZE)
|
||||
return 0;
|
||||
|
||||
os = ASN1_OCTET_STRING_new();
|
||||
if (os == NULL)
|
||||
return 0;
|
||||
|
||||
if (!ASN1_OCTET_STRING_set(os, priv, len)) {
|
||||
ASN1_OCTET_STRING_free(os);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey->pkey.ptr = os;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int poly1305_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
|
||||
|
||||
if (priv == NULL) {
|
||||
*len = POLY1305_KEY_SIZE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (os == NULL || *len < POLY1305_KEY_SIZE)
|
||||
return 0;
|
||||
|
||||
memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os));
|
||||
*len = POLY1305_KEY_SIZE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
poly1305_set_priv_key,
|
||||
NULL,
|
||||
poly1305_get_priv_key,
|
||||
NULL,
|
||||
};
|
@ -1,4 +1,3 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
siphash.c \
|
||||
siphash_ameth.c
|
||||
siphash.c
|
||||
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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 "crypto/asn1.h"
|
||||
#include "crypto/siphash.h"
|
||||
#include "siphash_local.h"
|
||||
#include "crypto/evp.h"
|
||||
|
||||
/*
|
||||
* SIPHASH "ASN1" method. This is just here to indicate the maximum
|
||||
* SIPHASH output length and to free up a SIPHASH key.
|
||||
*/
|
||||
|
||||
static int siphash_size(const EVP_PKEY *pkey)
|
||||
{
|
||||
return SIPHASH_MAX_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
static void siphash_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 siphash_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 siphash_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b));
|
||||
}
|
||||
|
||||
static int siphash_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
|
||||
size_t len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os;
|
||||
|
||||
if (pkey->pkey.ptr != NULL || len != SIPHASH_KEY_SIZE)
|
||||
return 0;
|
||||
|
||||
os = ASN1_OCTET_STRING_new();
|
||||
if (os == NULL)
|
||||
return 0;
|
||||
|
||||
if (!ASN1_OCTET_STRING_set(os, priv, len)) {
|
||||
ASN1_OCTET_STRING_free(os);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey->pkey.ptr = os;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int siphash_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
|
||||
|
||||
if (priv == NULL) {
|
||||
*len = SIPHASH_KEY_SIZE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (os == NULL || *len < SIPHASH_KEY_SIZE)
|
||||
return 0;
|
||||
|
||||
memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os));
|
||||
*len = SIPHASH_KEY_SIZE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD siphash_asn1_meth = {
|
||||
EVP_PKEY_SIPHASH,
|
||||
EVP_PKEY_SIPHASH,
|
||||
0,
|
||||
|
||||
"SIPHASH",
|
||||
"OpenSSL SIPHASH method",
|
||||
|
||||
0, 0, siphash_pkey_public_cmp, 0,
|
||||
|
||||
0, 0, 0,
|
||||
|
||||
siphash_size,
|
||||
0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
siphash_key_free,
|
||||
siphash_pkey_ctrl,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
siphash_set_priv_key,
|
||||
NULL,
|
||||
siphash_get_priv_key,
|
||||
NULL,
|
||||
};
|
Loading…
Reference in new issue