KMAC implementation using EVP_MAC

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/7597)
This commit is contained in:
Shane Lontis 2018-11-09 14:00:05 +10:00 committed by Pauli
parent 7dc6875c55
commit 6e624a6453
18 changed files with 761 additions and 5 deletions

View file

@ -5,7 +5,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
md2 md4 md5 sha mdc2 gmac hmac ripemd whrlpool poly1305 blake2 \
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
err comp ocsp cms ts srp cmac ct async
err comp ocsp cms ts srp cmac ct async kmac
LIBS=../libcrypto
SOURCE[../libcrypto]=\

View file

@ -803,6 +803,8 @@ EVP_F_EVP_SIGNFINAL:107:EVP_SignFinal
EVP_F_EVP_VERIFYFINAL:108:EVP_VerifyFinal
EVP_F_GMAC_CTRL:215:gmac_ctrl
EVP_F_INT_CTX_NEW:157:int_ctx_new
EVP_F_KMAC_CTRL:217:kmac_ctrl
EVP_F_KMAC_INIT:218:kmac_init
EVP_F_OK_NEW:200:ok_new
EVP_F_PKCS5_PBE_KEYIVGEN:117:PKCS5_PBE_keyivgen
EVP_F_PKCS5_V2_PBE_KEYIVGEN:118:PKCS5_v2_PBE_keyivgen
@ -2249,6 +2251,7 @@ EVP_R_GET_RAW_KEY_FAILED:182:get raw key failed
EVP_R_ILLEGAL_SCRYPT_PARAMETERS:171:illegal scrypt parameters
EVP_R_INITIALIZATION_ERROR:134:initialization error
EVP_R_INPUT_NOT_INITIALIZED:111:input not initialized
EVP_R_INVALID_CUSTOM_LENGTH:185:invalid custom length
EVP_R_INVALID_DIGEST:152:invalid digest
EVP_R_INVALID_FIPS_MODE:168:invalid fips mode
EVP_R_INVALID_KEY:163:invalid key

View file

@ -17,6 +17,8 @@ void openssl_add_all_macs_int(void)
#endif
EVP_add_mac(&gmac_meth);
EVP_add_mac(&hmac_meth);
EVP_add_mac(&kmac128_meth);
EVP_add_mac(&kmac256_meth);
#ifndef OPENSSL_NO_SIPHASH
EVP_add_mac(&siphash_meth);
#endif

View file

@ -143,6 +143,8 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, 0), "EVP_VerifyFinal"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_GMAC_CTRL, 0), "gmac_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_INT_CTX_NEW, 0), "int_ctx_new"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_KMAC_CTRL, 0), "kmac_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_KMAC_INIT, 0), "kmac_init"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_OK_NEW, 0), "ok_new"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_PBE_KEYIVGEN, 0), "PKCS5_PBE_keyivgen"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_PBE_KEYIVGEN, 0),
@ -215,6 +217,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
"initialization error"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INPUT_NOT_INITIALIZED),
"input not initialized"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_CUSTOM_LENGTH),
"invalid custom length"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST), "invalid digest"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"},

View file

@ -59,6 +59,11 @@ static int shake_init(EVP_MD_CTX *evp_ctx)
return init(evp_ctx, '\x1f');
}
static int kmac_init(EVP_MD_CTX *evp_ctx)
{
return init(evp_ctx, '\x04');
}
static int sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
@ -395,6 +400,7 @@ const EVP_MD *EVP_shake##bitlen(void) \
}; \
return &shake##bitlen##_md; \
}
#endif
EVP_MD_SHA3(224)
@ -404,3 +410,27 @@ EVP_MD_SHA3(512)
EVP_MD_SHAKE(128)
EVP_MD_SHAKE(256)
# define EVP_MD_KECCAK_KMAC(bitlen) \
const EVP_MD *evp_keccak_kmac##bitlen(void) \
{ \
static const EVP_MD kmac_##bitlen##_md = { \
-1, \
0, \
2 * bitlen / 8, \
EVP_MD_FLAG_XOF, \
kmac_init, \
sha3_update, \
sha3_final, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
sizeof(KECCAK1600_CTX), \
shake_ctrl \
}; \
return &kmac_##bitlen##_md; \
}
EVP_MD_KECCAK_KMAC(128)
EVP_MD_KECCAK_KMAC(256)

View file

@ -131,9 +131,15 @@ struct evp_mac_st {
extern const EVP_MAC cmac_meth;
extern const EVP_MAC gmac_meth;
extern const EVP_MAC hmac_meth;
extern const EVP_MAC kmac128_meth;
extern const EVP_MAC kmac256_meth;
extern const EVP_MAC siphash_meth;
extern const EVP_MAC poly1305_meth;
/* Internal keccak algorithms used for KMAC */
const EVP_MD *evp_keccak_kmac128(void);
const EVP_MD *evp_keccak_kmac256(void);
/*
* This function is internal for now, but can be made external when needed.
* The documentation would read:

3
crypto/kmac/build.info Normal file
View file

@ -0,0 +1,3 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=kmac.c

469
crypto/kmac/kmac.c Normal file
View file

@ -0,0 +1,469 @@
/*
* Copyright 2018 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
*/
/*
* See SP800-185 "Appendix A - KMAC, .... in Terms of Keccak[c]"
*
* Inputs are:
* K = Key (len(K) < 2^2040 bits)
* X = Input
* L = Output length (0 <= L < 2^2040 bits)
* S = Customization String Default="" (len(S) < 2^2040 bits)
*
* KMAC128(K, X, L, S)
* {
* newX = bytepad(encode_string(K), 168) || X || right_encode(L).
* T = bytepad(encode_string(KMAC) || encode_string(S), 168).
* return KECCAK[256](T || newX || 00, L).
* }
*
* KMAC256(K, X, L, S)
* {
* newX = bytepad(encode_string(K), 136) || X || right_encode(L).
* T = bytepad(encode_string(KMAC) || encode_string(S), 136).
* return KECCAK[512](T || newX || 00, L).
* }
*
* KMAC128XOF(K, X, L, S)
* {
* newX = bytepad(encode_string(K), 168) || X || right_encode(0).
* T = bytepad(encode_string(KMAC) || encode_string(S), 168).
* return KECCAK[256](T || newX || 00, L).
* }
*
* KMAC256XOF(K, X, L, S)
* {
* newX = bytepad(encode_string(K), 136) || X || right_encode(0).
* T = bytepad(encode_string(KMAC) || encode_string(S), 136).
* return KECCAK[512](T || newX || 00, L).
* }
*
*/
#include <stdlib.h>
#include <openssl/evp.h>
#include "internal/cryptlib.h"
#include "internal/evp_int.h"
#define KMAC_MAX_BLOCKSIZE ((1600 - 128*2) / 8) /* 168 */
#define KMAC_MIN_BLOCKSIZE ((1600 - 256*2) / 8) /* 136 */
/* Length encoding will be a 1 byte size + length in bits (2 bytes max) */
#define KMAC_MAX_ENCODED_HEADER_LEN 3
/*
* Custom string max size is chosen such that:
* len(encoded_string(custom) + len(kmac_encoded_string) <= KMAC_MIN_BLOCKSIZE
* i.e: (KMAC_MAX_CUSTOM + KMAC_MAX_ENCODED_LEN) + 6 <= 136
*/
#define KMAC_MAX_CUSTOM 127
/* Maximum size of encoded custom string */
#define KMAC_MAX_CUSTOM_ENCODED (KMAC_MAX_CUSTOM + KMAC_MAX_ENCODED_HEADER_LEN)
/* Maximum key size in bytes = 2040 / 8 */
#define KMAC_MAX_KEY 255
/*
* Maximum Encoded Key size will be padded to a multiple of the blocksize
* i.e KMAC_MAX_KEY + KMAC_MAX_ENCODED_LEN = 258
* Padded to a multiple of KMAC_MAX_BLOCKSIZE
*/
#define KMAC_MAX_KEY_ENCODED (KMAC_MAX_BLOCKSIZE * 2)
/* Fixed value of encode_string("KMAC") */
static const unsigned char kmac_string[] = {
0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43
};
#define KMAC_FLAG_XOF_MODE 1
/* typedef EVP_MAC_IMPL */
struct evp_mac_impl_st {
EVP_MD_CTX *ctx;
const EVP_MD *md;
size_t out_len;
int key_len;
int custom_len;
/* If xof_mode = 1 then we use right_encode(0) */
int xof_mode;
/* key and custom are stored in encoded form */
unsigned char key[KMAC_MAX_KEY_ENCODED];
unsigned char custom[KMAC_MAX_CUSTOM_ENCODED];
};
static int encode_string(unsigned char *out, int *out_len,
const unsigned char *in, int in_len);
static int right_encode(unsigned char *out, int *out_len, size_t bits);
static int bytepad(unsigned char *out, int *out_len,
const unsigned char *in1, int in1_len,
const unsigned char *in2, int in2_len,
int w);
static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
const unsigned char *in, int in_len,
int w);
static int kmac_ctrl_str(EVP_MAC_IMPL *kctx, const char *type,
const char *value);
static void kmac_free(EVP_MAC_IMPL *kctx)
{
if (kctx != NULL) {
EVP_MD_CTX_free(kctx->ctx);
OPENSSL_cleanse(kctx->key, kctx->key_len);
OPENSSL_cleanse(kctx->custom, kctx->custom_len);
OPENSSL_free(kctx);
}
}
static EVP_MAC_IMPL *kmac_new(const EVP_MD *md)
{
EVP_MAC_IMPL *kctx = NULL;
if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL
|| (kctx->ctx = EVP_MD_CTX_new()) == NULL) {
kmac_free(kctx);
return NULL;
}
kctx->md = md;
kctx->out_len = md->md_size;
return kctx;
}
static EVP_MAC_IMPL *kmac128_new(void)
{
return kmac_new(evp_keccak_kmac128());
}
static EVP_MAC_IMPL *kmac256_new(void)
{
return kmac_new(evp_keccak_kmac256());
}
static int kmac_copy(EVP_MAC_IMPL *gdst, EVP_MAC_IMPL *gsrc)
{
gdst->md = gsrc->md;
gdst->out_len = gsrc->out_len;
gdst->key_len = gsrc->key_len;
gdst->custom_len = gsrc->custom_len;
gdst->xof_mode = gsrc->xof_mode;
memcpy(gdst->key, gsrc->key, gsrc->key_len);
memcpy(gdst->custom, gsrc->custom, gdst->custom_len);
return EVP_MD_CTX_copy(gdst->ctx, gsrc->ctx);
}
/*
* The init() assumes that any ctrl methods are set beforehand for
* md, key and custom. Setting the fields afterwards will have no
* effect on the output mac.
*/
static int kmac_init(EVP_MAC_IMPL *kctx)
{
EVP_MD_CTX *ctx = kctx->ctx;
unsigned char out[KMAC_MAX_BLOCKSIZE];
int out_len, block_len;
/* Check key has been set */
if (kctx->key_len == 0) {
EVPerr(EVP_F_KMAC_INIT, EVP_R_NO_KEY_SET);
return 0;
}
if (!EVP_DigestInit_ex(kctx->ctx, kctx->md, NULL))
return 0;
block_len = EVP_MD_block_size(kctx->md);
/* Set default custom string if it is not already set */
if (kctx->custom_len == 0)
(void)kmac_ctrl_str(kctx, "custom", "");
return bytepad(out, &out_len, kmac_string, sizeof(kmac_string),
kctx->custom, kctx->custom_len, block_len)
&& EVP_DigestUpdate(ctx, out, out_len)
&& EVP_DigestUpdate(ctx, kctx->key, kctx->key_len);
}
static size_t kmac_size(EVP_MAC_IMPL *kctx)
{
return kctx->out_len;
}
static int kmac_update(EVP_MAC_IMPL *kctx, const unsigned char *data,
size_t datalen)
{
return EVP_DigestUpdate(kctx->ctx, data, datalen);
}
static int kmac_final(EVP_MAC_IMPL *kctx, unsigned char *out)
{
EVP_MD_CTX *ctx = kctx->ctx;
int lbits, len;
unsigned char encoded_outlen[KMAC_MAX_ENCODED_HEADER_LEN];
/* KMAC XOF mode sets the encoded length to 0 */
lbits = (kctx->xof_mode ? 0 : (kctx->out_len * 8));
return right_encode(encoded_outlen, &len, lbits)
&& EVP_DigestUpdate(ctx, encoded_outlen, len)
&& EVP_DigestFinalXOF(ctx, out, kctx->out_len);
}
/*
* The following Ctrl functions can be set any time before final():
* - EVP_MAC_CTRL_SET_SIZE: The requested output length.
* - EVP_MAC_CTRL_SET_XOF: If set, this indicates that right_encoded(0) is
* part of the digested data, otherwise it uses
* right_encoded(requested output length).
* All other Ctrl functions should be set before init().
*/
static int kmac_ctrl(EVP_MAC_IMPL *kctx, int cmd, va_list args)
{
const unsigned char *p;
size_t len;
size_t size;
switch (cmd) {
case EVP_MAC_CTRL_SET_XOF:
kctx->xof_mode = va_arg(args, int);
return 1;
case EVP_MAC_CTRL_SET_SIZE:
size = va_arg(args, size_t);
kctx->out_len = size;
return 1;
case EVP_MAC_CTRL_SET_KEY:
p = va_arg(args, const unsigned char *);
len = va_arg(args, size_t);
if (len < 4 || len > KMAC_MAX_KEY) {
EVPerr(EVP_F_KMAC_CTRL, EVP_R_INVALID_KEY_LENGTH);
return 0;
}
return kmac_bytepad_encode_key(kctx->key, &kctx->key_len, p, len,
EVP_MD_block_size(kctx->md));
case EVP_MAC_CTRL_SET_CUSTOM:
p = va_arg(args, const unsigned char *);
len = va_arg(args, size_t);
if (len > KMAC_MAX_CUSTOM) {
EVPerr(EVP_F_KMAC_CTRL, EVP_R_INVALID_CUSTOM_LENGTH);
return 0;
}
return encode_string(kctx->custom, &kctx->custom_len, p, len);
default:
return -2;
}
}
static int kmac_ctrl_int(EVP_MAC_IMPL *kctx, int cmd, ...)
{
int rv;
va_list args;
va_start(args, cmd);
rv = kmac_ctrl(kctx, cmd, args);
va_end(args);
return rv;
}
static int kmac_ctrl_str_cb(void *kctx, int cmd, void *buf, size_t buflen)
{
return kmac_ctrl_int(kctx, cmd, buf, buflen);
}
static int kmac_ctrl_str(EVP_MAC_IMPL *kctx, const char *type,
const char *value)
{
if (value == NULL)
return 0;
if (strcmp(type, "outlen") == 0)
return kmac_ctrl_int(kctx, EVP_MAC_CTRL_SET_SIZE, (size_t)atoi(value));
if (strcmp(type, "xof") == 0)
return kmac_ctrl_int(kctx, EVP_MAC_CTRL_SET_XOF, atoi(value));
if (strcmp(type, "key") == 0)
return EVP_str2ctrl(kmac_ctrl_str_cb, kctx, EVP_MAC_CTRL_SET_KEY,
value);
if (strcmp(type, "hexkey") == 0)
return EVP_hex2ctrl(kmac_ctrl_str_cb, kctx, EVP_MAC_CTRL_SET_KEY,
value);
if (strcmp(type, "custom") == 0)
return EVP_str2ctrl(kmac_ctrl_str_cb, kctx, EVP_MAC_CTRL_SET_CUSTOM,
value);
if (strcmp(type, "hexcustom") == 0)
return EVP_hex2ctrl(kmac_ctrl_str_cb, kctx, EVP_MAC_CTRL_SET_CUSTOM,
value);
return -2;
}
/*
* Encoding/Padding Methods.
*/
/* Returns the number of bytes required to store 'bits' into a byte array */
static unsigned int get_encode_size(size_t bits)
{
unsigned int cnt = 0, sz = sizeof(size_t);
while (bits && (cnt < sz)) {
++cnt;
bits >>= 8;
}
/* If bits is zero 1 byte is required */
if (cnt == 0)
cnt = 1;
return cnt;
}
/*
* Convert an integer into bytes . The number of bytes is appended
* to the end of the buffer. Returns an array of bytes 'out' of size
* *out_len.
*
* e.g if bits = 32, out[2] = { 0x20, 0x01 }
*
*/
static int right_encode(unsigned char *out, int *out_len, size_t bits)
{
unsigned int len = get_encode_size(bits);
int i;
/* The length is constrained to a single byte: 2040/8 = 255 */
if (len > 0xFF)
return 0;
/* MSB's are at the start of the bytes array */
for (i = len - 1; i >= 0; --i) {
out[i] = (unsigned char)(bits & 0xFF);
bits >>= 8;
}
/* Tack the length onto the end */
out[len] = (unsigned char)len;
/* The Returned length includes the tacked on byte */
*out_len = len + 1;
return 1;
}
/*
* Encodes a string with a left encoded length added. Note that the
* in_len is converted to bits (*8).
*
* e.g- in="KMAC" gives out[6] = { 0x01, 0x20, 0x4B, 0x4D, 0x41, 0x43 }
* len bits K M A C
*/
static int encode_string(unsigned char *out, int *out_len,
const unsigned char *in, int in_len)
{
if (in == NULL) {
*out_len = 0;
} else {
int i, bits, len;
bits = 8 * in_len;
len = get_encode_size(bits);
if (len > 0xFF)
return 0;
out[0] = len;
for (i = len; i > 0; --i) {
out[i] = (bits & 0xFF);
bits >>= 8;
}
memcpy(out + len + 1, in, in_len);
*out_len = (1 + len + in_len);
}
return 1;
}
/*
* Returns a zero padded encoding of the inputs in1 and an optional
* in2 (can be NULL). The padded output must be a multiple of the blocksize 'w'.
* The value of w is in bytes (< 256).
*
* The returned output is:
* zero_padded(multiple of w, (left_encode(w) || in1 [|| in2])
*/
static int bytepad(unsigned char *out, int *out_len,
const unsigned char *in1, int in1_len,
const unsigned char *in2, int in2_len, int w)
{
int len;
unsigned char *p = out;
int sz = w;
/* Left encoded w */
*p++ = 1;
*p++ = w;
/* || in1 */
memcpy(p, in1, in1_len);
p += in1_len;
/* [ || in2 ] */
if (in2 != NULL && in2_len > 0) {
memcpy(p, in2, in2_len);
p += in2_len;
}
/* Figure out the pad size (divisible by w) */
len = p - out;
while (len > sz) {
sz += w;
}
/* zero pad the end of the buffer */
memset(p, 0, sz - len);
*out_len = sz;
return 1;
}
/*
* Returns out = bytepad(encode_string(in), w)
*/
static int kmac_bytepad_encode_key(unsigned char *out, int *out_len,
const unsigned char *in, int in_len,
int w)
{
unsigned char tmp[KMAC_MAX_KEY + KMAC_MAX_ENCODED_HEADER_LEN];
int tmp_len;
if (!encode_string(tmp, &tmp_len, in, in_len))
return 0;
return bytepad(out, out_len, tmp, tmp_len, NULL, 0, w);
}
const EVP_MAC kmac128_meth = {
EVP_MAC_KMAC128,
kmac128_new,
kmac_copy,
kmac_free,
kmac_size,
kmac_init,
kmac_update,
kmac_final,
kmac_ctrl,
kmac_ctrl_str
};
const EVP_MAC kmac256_meth = {
EVP_MAC_KMAC256,
kmac256_new,
kmac_copy,
kmac_free,
kmac_size,
kmac_init,
kmac_update,
kmac_final,
kmac_ctrl,
kmac_ctrl_str
};

View file

@ -1079,7 +1079,7 @@ static const unsigned char so[7767] = {
0x28,0xCC,0x45,0x03,0x04, /* [ 7761] OBJ_gmac */
};
#define NUM_NID 1196
#define NUM_NID 1198
static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"UNDEF", "undefined", NID_undef},
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@ -2277,9 +2277,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]},
{"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]},
{"GMAC", "gmac", NID_gmac, 5, &so[7761]},
{"KMAC128", "kmac128", NID_kmac128},
{"KMAC256", "kmac256", NID_kmac256},
};
#define NUM_SN 1187
#define NUM_SN 1189
static const unsigned int sn_objs[NUM_SN] = {
364, /* "AD_DVCS" */
419, /* "AES-128-CBC" */
@ -2445,6 +2447,8 @@ static const unsigned int sn_objs[NUM_SN] = {
645, /* "ITU-T" */
646, /* "JOINT-ISO-ITU-T" */
773, /* "KISA" */
1196, /* "KMAC128" */
1197, /* "KMAC256" */
1063, /* "KxANY" */
1039, /* "KxDHE" */
1041, /* "KxDHE-PSK" */
@ -3470,7 +3474,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1093, /* "x509ExtAdmission" */
};
#define NUM_LN 1187
#define NUM_LN 1189
static const unsigned int ln_objs[NUM_LN] = {
363, /* "AD Time Stamping" */
405, /* "ANSI X9.62" */
@ -4266,6 +4270,8 @@ static const unsigned int ln_objs[NUM_LN] = {
956, /* "jurisdictionStateOrProvinceName" */
150, /* "keyBag" */
773, /* "kisa" */
1196, /* "kmac128" */
1197, /* "kmac256" */
1063, /* "kx-any" */
1039, /* "kx-dhe" */
1041, /* "kx-dhe-psk" */

View file

@ -1193,3 +1193,5 @@ magma_mac 1192
hmacWithSHA512_224 1193
hmacWithSHA512_256 1194
gmac 1195
kmac128 1196
kmac256 1197

View file

@ -13,6 +13,10 @@ iso 3 : identified-organization
# GMAC OID
iso 0 9797 3 4 : GMAC : gmac
# There are no OIDs for these yet...
: KMAC128 : kmac128
: KMAC256 : kmac256
# HMAC OIDs
identified-organization 6 1 5 5 8 1 1 : HMAC-MD5 : hmac-md5

View file

@ -169,9 +169,23 @@ This control expects two arguments: C<unsigned char *key>, C<size_t keylen>
Some MAC implementations require an IV, this control sets the IV.
=item B<EVP_MAC_CTRL_SET_CUSTOM>
This control expects two arguments: C<unsigned char *key>, C<size_t keylen>
Some MAC implementations (KMAC) require an Customization String,
this control sets the Customization String. The default value is "".
=item B<EVP_MAC_CTRL_SET_XOF>
This control expects one argument: C<int xof>
This option is used by KMAC.
=item B<EVP_MAC_CTRL_SET_FLAGS>
This control expects one arguments: C<unsigned long flags>
This control expects one argument: C<unsigned long flags>
These will set the MAC flags to the given numbers.
Some MACs do not support this option.
@ -335,6 +349,7 @@ F<./foo>)
L<EVP_MAC_CMAC(7)>,
L<EVP_MAC_GMAC(7)>,
L<EVP_MAC_HMAC(7)>,
L<EVP_MAC_KMAC(7)>,
L<EVP_MAC_SIPHASH(7)>,
L<EVP_MAC_POLY1305(7)>

94
doc/man7/EVP_MAC_KMAC.pod Normal file
View file

@ -0,0 +1,94 @@
=pod
=head1 NAME
EVP_MAC_KMAC - The KMAC EVP_MAC implementation
=head1 DESCRIPTION
Support for computing KMAC MACs through the B<EVP_MAC> API.
=head2 Numeric identity
B<EVP_MAC_KMAC128> and B<EVP_MAC_KMAC256> are the numeric identities for this
implementation, and can be used in functions like EVP_MAC_CTX_new_id() and
EVP_get_macbynid().
=head2 Supported controls
The supported controls are:
=over 4
=item B<EVP_MAC_CTRL_SET_KEY>
This must be set before calling EVP_MAC_init().
EVP_MAC_ctrl_str() takes two type strings for this control:
=over 4
=item "key"
The value string is used as is.
=item "hexkey"
The value string is expected to be a hexadecimal number, which will be
decoded before passing on as control value.
=back
=item B<EVP_MAC_CTRL_SET_CUSTOM>
This is an optional string value that can be set before calling EVP_MAC_init().
If it is not set it uses the default value "".
EVP_MAC_ctrl_str() takes two type strings for this control:
=over 4
=item "custom"
The value string is used as is.
=item "hexcustom"
The value string is expected to be a hexadecimal number, which will be
decoded before passing on as control value.
=back
=item B<EVP_MAC_CTRL_SET_SIZE>
EVP_MAC_ctrl_str() type string: "outlen"
This is an optional value string containing a decimal number. If it is not set
it uses the default value of 32 for EVP_MAC_KMAC128 and 64 for EVP_MAC_KMAC256.
This can be called any time before EVP_MAC_final().
=item B<EVP_MAC_CTRL_SET_XOF>
EVP_MAC_ctrl_str() type string: "xof"
The value string is expected to be an integer value of 1 or 0. Use 1 to enable
XOF mode. If XOF is enabled then the output len that is encoded as part of the
input stream is set to zero.
This can be called any time before EVP_MAC_final().
=back
=head1 SEE ALSO
L<EVP_MAC_ctrl(3)>, L<EVP_MAC(3)/CONTROLS>
=head1 COPYRIGHT
Copyright 2018 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
L<https://www.openssl.org/source/license.html>.
=cut

View file

@ -717,6 +717,7 @@ const EVP_MD *EVP_sha3_384(void);
const EVP_MD *EVP_sha3_512(void);
const EVP_MD *EVP_shake128(void);
const EVP_MD *EVP_shake256(void);
# ifndef OPENSSL_NO_MDC2
const EVP_MD *EVP_mdc2(void);
# endif
@ -990,6 +991,8 @@ void EVP_MD_do_all_sorted(void (*fn)
# define EVP_MAC_CMAC NID_cmac
# define EVP_MAC_GMAC NID_gmac
# define EVP_MAC_HMAC NID_hmac
# define EVP_MAC_KMAC128 NID_kmac128
# define EVP_MAC_KMAC256 NID_kmac256
# define EVP_MAC_SIPHASH NID_siphash
# define EVP_MAC_POLY1305 NID_poly1305
@ -1027,6 +1030,8 @@ void EVP_MAC_do_all_sorted(void (*fn)
# define EVP_MAC_CTRL_SET_CIPHER 0x05 /* EVP_CIPHER * */
# define EVP_MAC_CTRL_SET_SIZE 0x06 /* size_t */
# define EVP_MAC_CTRL_SET_IV 0x07 /* unsigned char *, size_t */
# define EVP_MAC_CTRL_SET_CUSTOM 0x08 /* unsigned char *, size_t */
# define EVP_MAC_CTRL_SET_XOF 0x09 /* int */
/* PKEY stuff */
int EVP_PKEY_decrypt_old(unsigned char *dec_key,

View file

@ -113,6 +113,8 @@ int ERR_load_EVP_strings(void);
# define EVP_F_EVP_VERIFYFINAL 108
# define EVP_F_GMAC_CTRL 215
# define EVP_F_INT_CTX_NEW 157
# define EVP_F_KMAC_CTRL 217
# define EVP_F_KMAC_INIT 218
# define EVP_F_OK_NEW 200
# define EVP_F_PKCS5_PBE_KEYIVGEN 117
# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118
@ -159,6 +161,7 @@ int ERR_load_EVP_strings(void);
# define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171
# define EVP_R_INITIALIZATION_ERROR 134
# define EVP_R_INPUT_NOT_INITIALIZED 111
# define EVP_R_INVALID_CUSTOM_LENGTH 185
# define EVP_R_INVALID_DIGEST 152
# define EVP_R_INVALID_FIPS_MODE 168
# define EVP_R_INVALID_KEY 163

View file

@ -49,6 +49,14 @@
#define NID_gmac 1195
#define OBJ_gmac OBJ_iso,0L,9797L,3L,4L
#define SN_kmac128 "KMAC128"
#define LN_kmac128 "kmac128"
#define NID_kmac128 1196
#define SN_kmac256 "KMAC256"
#define LN_kmac256 "kmac256"
#define NID_kmac256 1197
#define SN_hmac_md5 "HMAC-MD5"
#define LN_hmac_md5 "hmac-md5"
#define NID_hmac_md5 780

View file

@ -847,6 +847,8 @@ typedef struct mac_data_st {
/* Expected output */
unsigned char *output;
size_t output_len;
unsigned char *custom;
size_t custom_len;
/* Collection of controls */
STACK_OF(OPENSSL_STRING) *controls;
} MAC_DATA;
@ -929,6 +931,7 @@ static void mac_test_cleanup(EVP_TEST *t)
OPENSSL_free(mdat->alg);
OPENSSL_free(mdat->key);
OPENSSL_free(mdat->iv);
OPENSSL_free(mdat->custom);
OPENSSL_free(mdat->input);
OPENSSL_free(mdat->output);
}
@ -942,6 +945,8 @@ static int mac_test_parse(EVP_TEST *t,
return parse_bin(value, &mdata->key, &mdata->key_len);
if (strcmp(keyword, "IV") == 0)
return parse_bin(value, &mdata->iv, &mdata->iv_len);
if (strcmp(keyword, "Custom") == 0)
return parse_bin(value, &mdata->custom, &mdata->custom_len);
if (strcmp(keyword, "Algorithm") == 0) {
mdata->alg = OPENSSL_strdup(value);
if (!mdata->alg)
@ -1124,6 +1129,17 @@ static int mac_test_run_mac(EVP_TEST *t)
t->err = "MAC_CTRL_ERROR";
goto err;
}
if (expected->custom != NULL) {
rv = EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_CUSTOM,
expected->custom, expected->custom_len);
if (rv == -2) {
t->err = "MAC_CTRL_INVALID";
goto err;
} else if (rv <= 0) {
t->err = "MAC_CTRL_ERROR";
goto err;
}
}
if (expected->iv != NULL) {
rv = EVP_MAC_ctrl(ctx, EVP_MAC_CTRL_SET_IV,

View file

@ -455,6 +455,92 @@ Input = 68F2E77696CE7AE8E2CA4EC588E541002E58495C08000F101112131415161718191A1B1C
Output = 00BDA1B7E87608BCBF470F12157F4C07
Title = KMAC Tests (From NIST)
MAC = KMAC128
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 00010203
Custom = ""
Output = E5780B0D3EA6F7D3A429C5706AA43A00FADBD7D49628839E3187243F456EE14E
Ctrl = xof:0
MAC = KMAC128
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 00010203
Custom = "My Tagged Application"
Output = 3B1FBA963CD8B0B59E8C1A6D71888B7143651AF8BA0A7070C0979E2811324AA5
MAC = KMAC128
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
Custom = "My Tagged Application"
Output = 1F5B4E6CCA02209E0DCB5CA635B89A15E271ECC760071DFD805FAA38F9729230
Ctrl = outlen:32
MAC = KMAC256
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 00010203
Custom = "My Tagged Application"
Output = 20C570C31346F703C9AC36C61C03CB64C3970D0CFC787E9B79599D273A68D2F7F69D4CC3DE9D104A351689F27CF6F5951F0103F33F4F24871024D9C27773A8DD
MAC = KMAC256
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
Custom = ""
Output = 75358CF39E41494E949707927CEE0AF20A3FF553904C86B08F21CC414BCFD691589D27CF5E15369CBBFF8B9A4C2EB17800855D0235FF635DA82533EC6B759B69
MAC = KMAC256
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
Custom = "My Tagged Application"
Output = B58618F71F92E1D56C1B8C55DDD7CD188B97B4CA4D99831EB2699A837DA2E4D970FBACFDE50033AEA585F1A2708510C32D07880801BD182898FE476876FC8965
Ctrl = outlen:64
Title = KMAC XOF Tests (From NIST)
MAC = KMAC128
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 00010203
Output = CD83740BBD92CCC8CF032B1481A0F4460E7CA9DD12B08A0C4031178BACD6EC35
Ctrl = xof:1
MAC = KMAC128
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 00010203
Custom = "My Tagged Application"
Output = 31A44527B4ED9F5C6101D11DE6D26F0620AA5C341DEF41299657FE9DF1A3B16C
Ctrl = xof:1
MAC = KMAC128
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
Custom = "My Tagged Application"
Output = 47026C7CD793084AA0283C253EF658490C0DB61438B8326FE9BDDF281B83AE0F
Ctrl = xof:1
Ctrl = outlen:32
MAC = KMAC256
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 00010203
Custom = "My Tagged Application"
Output = 1755133F1534752AAD0748F2C706FB5C784512CAB835CD15676B16C0C6647FA96FAA7AF634A0BF8FF6DF39374FA00FAD9A39E322A7C92065A64EB1FB0801EB2B
Ctrl = xof:1
MAC = KMAC256
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
Custom = ""
Output = FF7B171F1E8A2B24683EED37830EE797538BA8DC563F6DA1E667391A75EDC02CA633079F81CE12A25F45615EC89972031D18337331D24CEB8F8CA8E6A19FD98B
Ctrl = xof:1
MAC = KMAC256
Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
Custom = "My Tagged Application"
Output = D5BE731C954ED7732846BB59DBE3A8E30F83E77A4BFF4459F2F1C2B4ECEBB8CE67BA01C62E8AB8578D2D499BD1BB276768781190020A306A97DE281DCC30305D
Ctrl = outlen:64
Ctrl = xof:1
Title = Poly1305 Tests (from RFC 7539 and others)
MAC = Poly1305