Latest update

This commit is contained in:
2018-11-01 00:59:10 +09:00
parent 95369e3f0a
commit 35dea6db7e
107 changed files with 4513 additions and 1163 deletions
+2 -1
View File
@@ -17,7 +17,8 @@
# include <unistd.h>
# if _POSIX_VERSION >= 200112L
# if _POSIX_VERSION >= 200112L \
&& (_POSIX_VERSION < 200809L || defined(__GLIBC__))
# include <pthread.h>
+1 -1
View File
@@ -1077,7 +1077,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
* is not only slower but also makes each bit vulnerable to
* EM (and likely other) side-channel attacks like One&Done
* (for details see "One&Done: A Single-Decryption EM-Based
* Attack on OpenSSLs Constant-Time Blinded RSA" by M. Alam,
* Attack on OpenSSL's Constant-Time Blinded RSA" by M. Alam,
* H. Khan, M. Dey, N. Sinha, R. Callan, A. Zajic, and
* M. Prvulovic, in USENIX Security'18)
*/
+1 -1
View File
@@ -1,2 +1,2 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_pmeth.c
SOURCE[../../libcrypto]=cmac.c cm_ameth.c cm_meth.c
+3 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2010-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
@@ -10,7 +10,6 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/cmac.h>
#include "internal/asn1_int.h"
/*
@@ -25,8 +24,8 @@ static int cmac_size(const EVP_PKEY *pkey)
static void cmac_key_free(EVP_PKEY *pkey)
{
CMAC_CTX *cmctx = EVP_PKEY_get0(pkey);
CMAC_CTX_free(cmctx);
EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey);
EVP_MAC_CTX_free(cmctx);
}
const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = {
+164
View File
@@ -0,0 +1,164 @@
/*
* 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
*/
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
#include <openssl/cmac.h>
#include "internal/evp_int.h"
/* local CMAC pkey structure */
/* typedef EVP_MAC_IMPL */
struct evp_mac_impl_st {
/* tmpcipher and tmpengine are set to NULL after a CMAC_Init call */
const EVP_CIPHER *tmpcipher; /* cached CMAC cipher */
const ENGINE *tmpengine; /* cached CMAC cipher engine */
CMAC_CTX *ctx;
};
static EVP_MAC_IMPL *cmac_new(void)
{
EVP_MAC_IMPL *cctx;
if ((cctx = OPENSSL_zalloc(sizeof(*cctx))) == NULL
|| (cctx->ctx = CMAC_CTX_new()) == NULL) {
OPENSSL_free(cctx);
cctx = NULL;
}
return cctx;
}
static void cmac_free(EVP_MAC_IMPL *cctx)
{
if (cctx != NULL) {
CMAC_CTX_free(cctx->ctx);
OPENSSL_free(cctx);
}
}
static int cmac_copy(EVP_MAC_IMPL *cdst, EVP_MAC_IMPL *csrc)
{
if (!CMAC_CTX_copy(cdst->ctx, csrc->ctx))
return 0;
cdst->tmpengine = csrc->tmpengine;
cdst->tmpcipher = csrc->tmpcipher;
return 1;
}
static size_t cmac_size(EVP_MAC_IMPL *cctx)
{
return EVP_CIPHER_CTX_block_size(CMAC_CTX_get0_cipher_ctx(cctx->ctx));
}
static int cmac_init(EVP_MAC_IMPL *cctx)
{
int rv = CMAC_Init(cctx->ctx, NULL, 0, cctx->tmpcipher,
(ENGINE *)cctx->tmpengine);
cctx->tmpcipher = NULL;
cctx->tmpengine = NULL;
return rv;
}
static int cmac_update(EVP_MAC_IMPL *cctx, const unsigned char *data,
size_t datalen)
{
return CMAC_Update(cctx->ctx, data, datalen);
}
static int cmac_final(EVP_MAC_IMPL *cctx, unsigned char *out)
{
size_t hlen;
return CMAC_Final(cctx->ctx, out, &hlen);
}
static int cmac_ctrl(EVP_MAC_IMPL *cctx, int cmd, va_list args)
{
switch (cmd) {
case EVP_MAC_CTRL_SET_KEY:
{
const unsigned char *key = va_arg(args, const unsigned char *);
size_t keylen = va_arg(args, size_t);
int rv = CMAC_Init(cctx->ctx, key, keylen, cctx->tmpcipher,
(ENGINE *)cctx->tmpengine);
cctx->tmpcipher = NULL;
cctx->tmpengine = NULL;
return rv;
}
break;
case EVP_MAC_CTRL_SET_CIPHER:
cctx->tmpcipher = va_arg(args, const EVP_CIPHER *);
break;
case EVP_MAC_CTRL_SET_ENGINE:
cctx->tmpengine = va_arg(args, const ENGINE *);
break;
default:
return -2;
}
return 1;
}
static int cmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...)
{
int rv;
va_list args;
va_start(args, cmd);
rv = cmac_ctrl(hctx, cmd, args);
va_end(args);
return rv;
}
static int cmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen)
{
return cmac_ctrl_int(hctx, cmd, buf, buflen);
}
static int cmac_ctrl_str(EVP_MAC_IMPL *cctx, const char *type,
const char *value)
{
if (!value)
return 0;
if (strcmp(type, "cipher") == 0) {
const EVP_CIPHER *c = EVP_get_cipherbyname(value);
if (c == NULL)
return 0;
return cmac_ctrl_int(cctx, EVP_MAC_CTRL_SET_CIPHER, c);
}
if (strcmp(type, "key") == 0)
return EVP_str2ctrl(cmac_ctrl_str_cb, cctx, EVP_MAC_CTRL_SET_KEY,
value);
if (strcmp(type, "hexkey") == 0)
return EVP_hex2ctrl(cmac_ctrl_str_cb, cctx, EVP_MAC_CTRL_SET_KEY,
value);
return -2;
}
const EVP_MAC cmac_meth = {
EVP_MAC_CMAC,
cmac_new,
cmac_copy,
cmac_free,
cmac_size,
cmac_init,
cmac_update,
cmac_final,
cmac_ctrl,
cmac_ctrl_str
};
-161
View File
@@ -1,161 +0,0 @@
/*
* Copyright 2010-2016 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 <openssl/cmac.h>
#include "internal/evp_int.h"
/* The context structure and "key" is simply a CMAC_CTX */
static int pkey_cmac_init(EVP_PKEY_CTX *ctx)
{
ctx->data = CMAC_CTX_new();
if (ctx->data == NULL)
return 0;
ctx->keygen_info_count = 0;
return 1;
}
static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
{
if (!pkey_cmac_init(dst))
return 0;
if (!CMAC_CTX_copy(dst->data, src->data))
return 0;
return 1;
}
static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx)
{
CMAC_CTX_free(ctx->data);
}
static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
CMAC_CTX *cmkey = CMAC_CTX_new();
CMAC_CTX *cmctx = ctx->data;
if (cmkey == NULL)
return 0;
if (!CMAC_CTX_copy(cmkey, cmctx)) {
CMAC_CTX_free(cmkey);
return 0;
}
EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey);
return 1;
}
static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
if (!CMAC_Update(EVP_MD_CTX_pkey_ctx(ctx)->data, data, count))
return 0;
return 1;
}
static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
EVP_MD_CTX_set_update_fn(mctx, int_update);
return 1;
}
static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
EVP_MD_CTX *mctx)
{
return CMAC_Final(ctx->data, sig, siglen);
}
static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
CMAC_CTX *cmctx = ctx->data;
switch (type) {
case EVP_PKEY_CTRL_SET_MAC_KEY:
if (!p2 || p1 < 0)
return 0;
if (!CMAC_Init(cmctx, p2, p1, NULL, NULL))
return 0;
break;
case EVP_PKEY_CTRL_CIPHER:
if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine))
return 0;
break;
case EVP_PKEY_CTRL_MD:
if (ctx->pkey && !CMAC_CTX_copy(ctx->data,
(CMAC_CTX *)ctx->pkey->pkey.ptr))
return 0;
if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL))
return 0;
break;
default:
return -2;
}
return 1;
}
static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
if (!value) {
return 0;
}
if (strcmp(type, "cipher") == 0) {
const EVP_CIPHER *c;
c = EVP_get_cipherbyname(value);
if (!c)
return 0;
return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c);
}
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 cmac_pkey_meth = {
EVP_PKEY_CMAC,
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
pkey_cmac_init,
pkey_cmac_copy,
pkey_cmac_cleanup,
0, 0,
0,
pkey_cmac_keygen,
0, 0,
0, 0,
0, 0,
cmac_signctx_init,
cmac_signctx,
0, 0,
0, 0,
0, 0,
0, 0,
pkey_cmac_ctrl,
pkey_cmac_ctrl_str
};
+6
View File
@@ -327,6 +327,12 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
if (mctx == NULL)
goto err;
/* make sure L > N, otherwise we'll get trapped in an infinite loop */
if (L <= N) {
DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
goto err;
}
if (evpmd == NULL) {
if (N == 160)
evpmd = EVP_sha1();
+46 -14
View File
@@ -9,6 +9,7 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#include "internal/bn_int.h"
#include <openssl/bn.h>
#include <openssl/sha.h>
#include "dsa_locl.h"
@@ -23,6 +24,8 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
DSA_SIG *sig, DSA *dsa);
static int dsa_init(DSA *dsa);
static int dsa_finish(DSA *dsa);
static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
BN_CTX *ctx);
static DSA_METHOD openssl_dsa_meth = {
"OpenSSL DSA method",
@@ -178,9 +181,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
{
BN_CTX *ctx = NULL;
BIGNUM *k, *kinv = NULL, *r = *rp;
BIGNUM *l, *m;
BIGNUM *l;
int ret = 0;
int q_bits;
int q_bits, q_words;
if (!dsa->p || !dsa->q || !dsa->g) {
DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
@@ -189,8 +192,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
k = BN_new();
l = BN_new();
m = BN_new();
if (k == NULL || l == NULL || m == NULL)
if (k == NULL || l == NULL)
goto err;
if (ctx_in == NULL) {
@@ -201,9 +203,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
/* Preallocate space */
q_bits = BN_num_bits(dsa->q);
if (!BN_set_bit(k, q_bits)
|| !BN_set_bit(l, q_bits)
|| !BN_set_bit(m, q_bits))
q_words = bn_get_top(dsa->q);
if (!bn_wexpand(k, q_words + 2)
|| !bn_wexpand(l, q_words + 2))
goto err;
/* Get random k */
@@ -238,14 +240,17 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
* small timing information leakage. We then choose the sum that is
* one bit longer than the modulus.
*
* TODO: revisit the BN_copy aiming for a memory access agnostic
* conditional copy.
* There are some concerns about the efficacy of doing this. More
* specificly refer to the discussion starting with:
* https://github.com/openssl/openssl/pull/7486#discussion_r228323705
* The fix is to rework BN so these gymnastics aren't required.
*/
if (!BN_add(l, k, dsa->q)
|| !BN_add(m, l, dsa->q)
|| !BN_copy(k, BN_num_bits(l) > q_bits ? l : m))
|| !BN_add(k, l, dsa->q))
goto err;
BN_consttime_swap(BN_is_bit_set(l, q_bits), k, l, q_words + 2);
if ((dsa)->meth->bn_mod_exp != NULL) {
if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx,
dsa->method_mont_p))
@@ -258,8 +263,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
if (!BN_mod(r, r, dsa->q, ctx))
goto err;
/* Compute part of 's = inv(k) (m + xr) mod q' */
if ((kinv = BN_mod_inverse(NULL, k, dsa->q, ctx)) == NULL)
/* Compute part of 's = inv(k) (m + xr) mod q' */
if ((kinv = dsa_mod_inverse_fermat(k, dsa->q, ctx)) == NULL)
goto err;
BN_clear_free(*kinvp);
@@ -273,7 +278,6 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
BN_CTX_free(ctx);
BN_clear_free(k);
BN_clear_free(l);
BN_clear_free(m);
return ret;
}
@@ -393,3 +397,31 @@ static int dsa_finish(DSA *dsa)
BN_MONT_CTX_free(dsa->method_mont_p);
return 1;
}
/*
* Compute the inverse of k modulo q.
* Since q is prime, Fermat's Little Theorem applies, which reduces this to
* mod-exp operation. Both the exponent and modulus are public information
* so a mod-exp that doesn't leak the base is sufficient. A newly allocated
* BIGNUM is returned which the caller must free.
*/
static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q,
BN_CTX *ctx)
{
BIGNUM *res = NULL;
BIGNUM *r, *e;
if ((r = BN_new()) == NULL)
return NULL;
BN_CTX_start(ctx);
if ((e = BN_CTX_get(ctx)) != NULL
&& BN_set_word(r, 2)
&& BN_sub(e, q, r)
&& BN_mod_exp_mont(r, k, e, q, ctx, NULL))
res = r;
else
BN_free(r);
BN_CTX_end(ctx);
return res;
}
+2 -2
View File
@@ -699,7 +699,7 @@ static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
return 0;
if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0)
if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
return 0;
kdf_md = EVP_get_digestbynid(kdfmd_nid);
@@ -864,7 +864,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
ecdh_nid = NID_dh_cofactor_kdf;
if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
kdf_type = EVP_PKEY_ECDH_KDF_X9_63;
if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
goto err;
} else
+3 -3
View File
@@ -206,8 +206,8 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
*/
cardinality_bits = BN_num_bits(cardinality);
group_top = bn_get_top(cardinality);
if ((bn_wexpand(k, group_top + 1) == NULL)
|| (bn_wexpand(lambda, group_top + 1) == NULL)) {
if ((bn_wexpand(k, group_top + 2) == NULL)
|| (bn_wexpand(lambda, group_top + 2) == NULL)) {
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
goto err;
}
@@ -244,7 +244,7 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
* k := scalar + 2*cardinality
*/
kbit = BN_is_bit_set(lambda, cardinality_bits);
BN_consttime_swap(kbit, k, lambda, group_top + 1);
BN_consttime_swap(kbit, k, lambda, group_top + 2);
group_top = bn_get_top(group->field);
if ((bn_wexpand(s->X, group_top) == NULL)
+2 -2
View File
@@ -209,7 +209,7 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
goto err;
/* Do KDF stuff */
if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen,
if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen,
dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
goto err;
rv = 1;
@@ -281,7 +281,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_EC_KDF_TYPE:
if (p1 == -2)
return dctx->kdf_type;
if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62)
if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_63)
return -2;
dctx->kdf_type = p1;
return 1;
+18 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-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
@@ -10,12 +10,13 @@
#include <string.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include "ec_lcl.h"
/* Key derivation function from X9.62/SECG */
/* Key derivation function from X9.63/SECG */
/* Way more than we will ever need */
#define ECDH_KDF_MAX (1 << 30)
int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md)
@@ -66,3 +67,17 @@ int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
EVP_MD_CTX_free(mctx);
return rv;
}
/*-
* The old name for ecdh_KDF_X9_63
* Retained for ABI compatibility
*/
#if OPENSSL_API_COMPAT < 0x10200000L
int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md)
{
return ecdh_KDF_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md);
}
#endif
+6
View File
@@ -740,6 +740,11 @@ EVP_F_EVP_DIGESTFINALXOF:174:EVP_DigestFinalXOF
EVP_F_EVP_DIGESTINIT_EX:128:EVP_DigestInit_ex
EVP_F_EVP_ENCRYPTFINAL_EX:127:EVP_EncryptFinal_ex
EVP_F_EVP_ENCRYPTUPDATE:167:EVP_EncryptUpdate
EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl
EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str
EVP_F_EVP_MAC_CTX_COPY:211:EVP_MAC_CTX_copy
EVP_F_EVP_MAC_CTX_NEW:213:EVP_MAC_CTX_new
EVP_F_EVP_MAC_INIT:212:EVP_MAC_init
EVP_F_EVP_MD_CTX_COPY_EX:110:EVP_MD_CTX_copy_ex
EVP_F_EVP_MD_SIZE:162:EVP_MD_size
EVP_F_EVP_OPENINIT:102:EVP_OpenInit
@@ -802,6 +807,7 @@ EVP_F_PKCS5_PBE_KEYIVGEN:117:PKCS5_PBE_keyivgen
EVP_F_PKCS5_V2_PBE_KEYIVGEN:118:PKCS5_v2_PBE_keyivgen
EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN:164:PKCS5_v2_PBKDF2_keyivgen
EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN:180:PKCS5_v2_scrypt_keyivgen
EVP_F_PKEY_MAC_INIT:214:pkey_mac_init
EVP_F_PKEY_SET_TYPE:158:pkey_set_type
EVP_F_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth
EVP_F_RC5_CTRL:125:rc5_ctrl
+2 -1
View File
@@ -12,7 +12,8 @@ SOURCE[../../libcrypto]=\
evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
e_chacha20_poly1305.c cmeth_lib.c
e_chacha20_poly1305.c cmeth_lib.c \
mac_lib.c c_allm.c pkey_mac.c
INCLUDE[e_aes.o]=.. ../modes
INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes
+22
View File
@@ -0,0 +1,22 @@
/*
* 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
*/
#include <openssl/evp.h>
#include "internal/evp_int.h"
void openssl_add_all_macs_int(void)
{
#ifndef OPENSSL_NO_CMAC
EVP_add_mac(&cmac_meth);
#endif
EVP_add_mac(&hmac_meth);
#ifndef OPENSSL_NO_SIPHASH
EVP_add_mac(&siphash_meth);
#endif
}
+6
View File
@@ -54,6 +54,11 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0),
"EVP_EncryptFinal_ex"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL, 0), "EVP_MAC_ctrl"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL_STR, 0), "EVP_MAC_ctrl_str"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_COPY, 0), "EVP_MAC_CTX_copy"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_NEW, 0), "EVP_MAC_CTX_new"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_INIT, 0), "EVP_MAC_init"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_CTX_COPY_EX, 0), "EVP_MD_CTX_copy_ex"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_SIZE, 0), "EVP_MD_size"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_OPENINIT, 0), "EVP_OpenInit"},
@@ -145,6 +150,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
"PKCS5_v2_PBKDF2_keyivgen"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0),
"PKCS5_v2_scrypt_keyivgen"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_INIT, 0), "pkey_mac_init"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"},
+27
View File
@@ -526,3 +526,30 @@ int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
{
return (ctx->flags & flags);
}
int EVP_str2ctrl(int (*cb)(void *ctx, int cmd, void *buf, size_t buflen),
void *ctx, int cmd, const char *value)
{
size_t len;
len = strlen(value);
if (len > INT_MAX)
return -1;
return cb(ctx, cmd, (void *)value, len);
}
int EVP_hex2ctrl(int (*cb)(void *ctx, int cmd, void *buf, size_t buflen),
void *ctx, int cmd, const char *hex)
{
unsigned char *bin;
long binlen;
int rv = -1;
bin = OPENSSL_hexstr2buf(hex, &binlen);
if (bin == NULL)
return 0;
if (binlen <= INT_MAX)
rv = cb(ctx, cmd, bin, binlen);
OPENSSL_free(bin);
return rv;
}
+5
View File
@@ -41,6 +41,11 @@ struct evp_cipher_ctx_st {
unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
} /* EVP_CIPHER_CTX */ ;
struct evp_mac_ctx_st {
const EVP_MAC *meth; /* Method structure */
void *data; /* Individual method data */
} /* EVP_MAC_CTX */;
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md,
+185
View File
@@ -0,0 +1,185 @@
/*
* 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
*/
#include <string.h>
#include <stdarg.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/ossl_typ.h>
#include "internal/nelem.h"
#include "internal/evp_int.h"
#include "evp_locl.h"
EVP_MAC_CTX *EVP_MAC_CTX_new_id(int id)
{
const EVP_MAC *mac = EVP_get_macbynid(id);
if (mac == NULL)
return NULL;
return EVP_MAC_CTX_new(mac);
}
EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac)
{
EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX));
if (ctx == NULL || (ctx->data = mac->new()) == NULL) {
EVPerr(EVP_F_EVP_MAC_CTX_NEW, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ctx);
ctx = NULL;
} else {
ctx->meth = mac;
}
return ctx;
}
void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx)
{
if (ctx != NULL && ctx->data != NULL) {
ctx->meth->free(ctx->data);
ctx->data = NULL;
}
OPENSSL_free(ctx);
}
int EVP_MAC_CTX_copy(EVP_MAC_CTX *dst, EVP_MAC_CTX *src)
{
EVP_MAC_IMPL *macdata;
if (src->data != NULL && !dst->meth->copy(dst->data, src->data))
return 0;
macdata = dst->data;
*dst = *src;
dst->data = macdata;
return 1;
}
const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx)
{
return ctx->meth;
}
size_t EVP_MAC_size(EVP_MAC_CTX *ctx)
{
if (ctx->data != NULL)
return ctx->meth->size(ctx->data);
/* If the MAC hasn't been initialized yet, we return zero */
return 0;
}
int EVP_MAC_init(EVP_MAC_CTX *ctx)
{
return ctx->meth->init(ctx->data);
}
int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen)
{
return ctx->meth->update(ctx->data, data, datalen);
}
int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen)
{
int l = ctx->meth->size(ctx->data);
if (l < 0)
return 0;
if (poutlen != NULL)
*poutlen = l;
if (out == NULL)
return 1;
return ctx->meth->final(ctx->data, out);
}
int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...)
{
int ok = -1;
va_list args;
va_start(args, cmd);
ok = EVP_MAC_vctrl(ctx, cmd, args);
va_end(args);
if (ok == -2)
EVPerr(EVP_F_EVP_MAC_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
return ok;
}
int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args)
{
int ok = 1;
if (ctx == NULL || ctx->meth == NULL)
return -2;
switch (cmd) {
#if 0
case ...:
/* code */
ok = 1;
break;
#endif
default:
if (ctx->meth->ctrl != NULL)
ok = ctx->meth->ctrl(ctx->data, cmd, args);
else
ok = -2;
break;
}
return ok;
}
int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value)
{
int ok = 1;
if (ctx == NULL || ctx->meth == NULL || ctx->meth->ctrl_str == NULL) {
EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
return -2;
}
ok = ctx->meth->ctrl_str(ctx->data, type, value);
if (ok == -2)
EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
return ok;
}
int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value)
{
size_t len;
len = strlen(value);
if (len > INT_MAX)
return -1;
return EVP_MAC_ctrl(ctx, cmd, value, len);
}
int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *hex)
{
unsigned char *bin;
long binlen;
int rv = -1;
bin = OPENSSL_hexstr2buf(hex, &binlen);
if (bin == NULL)
return 0;
if (binlen <= INT_MAX)
rv = EVP_MAC_ctrl(ctx, cmd, bin, (size_t)binlen);
OPENSSL_free(bin);
return rv;
}
int EVP_MAC_nid(const EVP_MAC *mac)
{
return mac->type;
}
+74 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-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
@@ -55,6 +55,22 @@ int EVP_add_digest(const EVP_MD *md)
return r;
}
int EVP_add_mac(const EVP_MAC *m)
{
int r;
if (m == NULL)
return 0;
r = OBJ_NAME_add(OBJ_nid2sn(m->type), OBJ_NAME_TYPE_MAC_METH,
(const char *)m);
if (r == 0)
return 0;
r = OBJ_NAME_add(OBJ_nid2ln(m->type), OBJ_NAME_TYPE_MAC_METH,
(const char *)m);
return r;
}
const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
{
const EVP_CIPHER *cp;
@@ -77,8 +93,20 @@ const EVP_MD *EVP_get_digestbyname(const char *name)
return cp;
}
const EVP_MAC *EVP_get_macbyname(const char *name)
{
const EVP_MAC *mp;
if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL))
return NULL;
mp = (const EVP_MAC *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MAC_METH);
return mp;
}
void evp_cleanup_int(void)
{
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MAC_METH);
OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
/*
@@ -178,3 +206,48 @@ void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
dc.arg = arg;
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
}
struct doall_mac {
void *arg;
void (*fn) (const EVP_MAC *ciph,
const char *from, const char *to, void *arg);
};
static void do_all_mac_fn(const OBJ_NAME *nm, void *arg)
{
struct doall_mac *dc = arg;
if (nm->alias)
dc->fn(NULL, nm->name, nm->data, dc->arg);
else
dc->fn((const EVP_MAC *)nm->data, nm->name, NULL, dc->arg);
}
void EVP_MAC_do_all(void (*fn)
(const EVP_MAC *ciph, const char *from, const char *to,
void *x), void *arg)
{
struct doall_mac dc;
/* Ignore errors */
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL);
dc.fn = fn;
dc.arg = arg;
OBJ_NAME_do_all(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
}
void EVP_MAC_do_all_sorted(void (*fn)
(const EVP_MAC *ciph, const char *from,
const char *to, void *x), void *arg)
{
struct doall_mac dc;
/* Ignore errors */
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL);
dc.fn = fn;
dc.arg = arg;
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
}
+5 -3
View File
@@ -319,7 +319,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
{
#ifndef OPENSSL_NO_CMAC
EVP_PKEY *ret = EVP_PKEY_new();
CMAC_CTX *cmctx = CMAC_CTX_new();
EVP_MAC_CTX *cmctx = EVP_MAC_CTX_new_id(EVP_MAC_CMAC);
if (ret == NULL
|| cmctx == NULL
@@ -328,7 +328,9 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
goto err;
}
if (!CMAC_Init(cmctx, priv, len, cipher, e)) {
if (EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_ENGINE, e) <= 0
|| EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_CIPHER, cipher) <= 0
|| EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_KEY, priv, len) <= 0) {
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
goto err;
}
@@ -338,7 +340,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
err:
EVP_PKEY_free(ret);
CMAC_CTX_free(cmctx);
EVP_MAC_CTX_free(cmctx);
return NULL;
#else
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
+427
View File
@@ -0,0 +1,427 @@
/*
* 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
*/
#include <openssl/err.h>
#include <openssl/evp.h>
#include "internal/evp_int.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 int pkey_mac_init(EVP_PKEY_CTX *ctx)
{
MAC_PKEY_CTX *hctx;
int nid = ctx->pmeth->pkey_id;
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);
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;
}
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, EVP_PKEY_CTX *src)
{
MAC_PKEY_CTX *sctx, *dctx;
if (!pkey_mac_init(dst))
return 0;
sctx = EVP_PKEY_CTX_get_data(src);
dctx = EVP_PKEY_CTX_get_data(dst);
if (!EVP_MAC_CTX_copy(dctx->ctx, sctx->ctx))
goto err;
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)
{
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
if (hctx != 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);
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 = EVP_MAC_CTX_new_id(nid);
if (cmkey == NULL)
return 0;
if (!EVP_MAC_CTX_copy(cmkey, hctx->ctx)) {
EVP_MAC_CTX_free(cmkey);
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 (set_key) {
if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))
!= EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->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;
}
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);
}
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:
{
int rv;
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;
}
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:
if (ctx->pkey != NULL
&& !EVP_MAC_CTX_copy(hctx->ctx,
(EVP_MAC_CTX *)ctx->pkey->pkey.ptr))
return 0;
if (!EVP_MAC_init(hctx->ctx))
return 0;
break;
default:
/* This should be dead code */
return 0;
}
break;
case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
return EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_SIZE, (size_t)p1);
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:
if (!EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1))
return 0;
break;
default:
/* This should be dead code */
return 0;
}
break;
case EVP_PKEY_CTRL_DIGESTINIT:
switch (hctx->type) {
case MAC_TYPE_RAW:
/* Ensure that we have attached the implementation */
if (!EVP_MAC_init(hctx->ctx))
return 0;
{
int rv;
ASN1_OCTET_STRING *key =
(ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
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;
}
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);
return EVP_MAC_ctrl_str(hctx->ctx, type, value);
}
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 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 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
};
+1 -1
View File
@@ -1,3 +1,3 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
hmac.c hm_ameth.c hm_pmeth.c
hmac.c hm_ameth.c hm_meth.c
+173
View File
@@ -0,0 +1,173 @@
/*
* 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
*/
#include <string.h>
#include <openssl/err.h>
#include <openssl/ossl_typ.h>
#include <openssl/asn1.h>
#include <openssl/hmac.h>
#include "internal/evp_int.h"
/* local HMAC context structure */
/* typedef EVP_MAC_IMPL */
struct evp_mac_impl_st {
/* tmpmd and tmpengine are set to NULL after a CMAC_Init call */
const EVP_MD *tmpmd; /* HMAC digest */
const ENGINE *tmpengine; /* HMAC digest engine */
HMAC_CTX *ctx; /* HMAC context */
};
static EVP_MAC_IMPL *hmac_new(void)
{
EVP_MAC_IMPL *hctx;
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL
|| (hctx->ctx = HMAC_CTX_new()) == NULL) {
OPENSSL_free(hctx);
return NULL;
}
return hctx;
}
static void hmac_free(EVP_MAC_IMPL *hctx)
{
if (hctx != NULL) {
HMAC_CTX_free(hctx->ctx);
OPENSSL_free(hctx);
}
}
static int hmac_copy(EVP_MAC_IMPL *hdst, EVP_MAC_IMPL *hsrc)
{
if (!HMAC_CTX_copy(hdst->ctx, hsrc->ctx))
return 0;
hdst->tmpengine = hsrc->tmpengine;
hdst->tmpmd = hsrc->tmpmd;
return 1;
}
static size_t hmac_size(EVP_MAC_IMPL *hctx)
{
return HMAC_size(hctx->ctx);
}
static int hmac_init(EVP_MAC_IMPL *hctx)
{
int rv = 1;
/* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */
if (hctx->tmpmd != NULL)
rv = HMAC_Init_ex(hctx->ctx, NULL, 0, hctx->tmpmd,
(ENGINE * )hctx->tmpengine);
hctx->tmpengine = NULL;
hctx->tmpmd = NULL;
return rv;
}
static int hmac_update(EVP_MAC_IMPL *hctx, const unsigned char *data,
size_t datalen)
{
return HMAC_Update(hctx->ctx, data, datalen);
}
static int hmac_final(EVP_MAC_IMPL *hctx, unsigned char *out)
{
unsigned int hlen;
return HMAC_Final(hctx->ctx, out, &hlen);
}
static int hmac_ctrl(EVP_MAC_IMPL *hctx, int cmd, va_list args)
{
switch (cmd) {
case EVP_MAC_CTRL_SET_FLAGS:
{
unsigned long flags = va_arg(args, unsigned long);
HMAC_CTX_set_flags(hctx->ctx, flags);
}
break;
case EVP_MAC_CTRL_SET_KEY:
{
const unsigned char *key = va_arg(args, const unsigned char *);
size_t keylen = va_arg(args, size_t);
int rv = HMAC_Init_ex(hctx->ctx, key, keylen, hctx->tmpmd,
(ENGINE *)hctx->tmpengine);
hctx->tmpengine = NULL;
hctx->tmpmd = NULL;
return rv;
}
break;
case EVP_MAC_CTRL_SET_MD:
hctx->tmpmd = va_arg(args, const EVP_MD *);
break;
case EVP_MAC_CTRL_SET_ENGINE:
hctx->tmpengine = va_arg(args, const ENGINE *);
break;
default:
return -2;
}
return 1;
}
static int hmac_ctrl_int(EVP_MAC_IMPL *hctx, int cmd, ...)
{
int rv;
va_list args;
va_start(args, cmd);
rv = hmac_ctrl(hctx, cmd, args);
va_end(args);
return rv;
}
static int hmac_ctrl_str_cb(void *hctx, int cmd, void *buf, size_t buflen)
{
return hmac_ctrl_int(hctx, cmd, buf, buflen);
}
static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type,
const char *value)
{
if (!value)
return 0;
if (strcmp(type, "digest") == 0) {
const EVP_MD *d = EVP_get_digestbyname(value);
if (d == NULL)
return 0;
return hmac_ctrl_int(hctx, EVP_MAC_CTRL_SET_MD, d);
}
if (strcmp(type, "key") == 0)
return EVP_str2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
value);
if (strcmp(type, "hexkey") == 0)
return EVP_hex2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
value);
return -2;
}
const EVP_MAC hmac_meth = {
EVP_MAC_HMAC,
hmac_new,
hmac_copy,
hmac_free,
hmac_size,
hmac_init,
hmac_update,
hmac_final,
hmac_ctrl,
hmac_ctrl_str
};
-212
View File
@@ -1,212 +0,0 @@
/*
* Copyright 2007-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
*/
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/err.h>
#include "internal/evp_int.h"
/* HMAC pkey context structure */
typedef struct {
const EVP_MD *md; /* MD for HMAC use */
ASN1_OCTET_STRING ktmp; /* Temp storage for key */
HMAC_CTX *ctx;
} HMAC_PKEY_CTX;
static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
{
HMAC_PKEY_CTX *hctx;
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
CRYPTOerr(CRYPTO_F_PKEY_HMAC_INIT, ERR_R_MALLOC_FAILURE);
return 0;
}
hctx->ktmp.type = V_ASN1_OCTET_STRING;
hctx->ctx = HMAC_CTX_new();
if (hctx->ctx == NULL) {
OPENSSL_free(hctx);
return 0;
}
ctx->data = hctx;
ctx->keygen_info_count = 0;
return 1;
}
static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx);
static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
{
HMAC_PKEY_CTX *sctx, *dctx;
/* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */
if (!pkey_hmac_init(dst))
return 0;
sctx = EVP_PKEY_CTX_get_data(src);
dctx = EVP_PKEY_CTX_get_data(dst);
dctx->md = sctx->md;
if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx))
goto err;
if (sctx->ktmp.data) {
if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
sctx->ktmp.data, sctx->ktmp.length))
goto err;
}
return 1;
err:
/* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */
pkey_hmac_cleanup (dst);
return 0;
}
static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
{
HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
if (hctx != NULL) {
HMAC_CTX_free(hctx->ctx);
OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
OPENSSL_free(hctx);
EVP_PKEY_CTX_set_data(ctx, NULL);
}
}
static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
ASN1_OCTET_STRING *hkey = NULL;
HMAC_PKEY_CTX *hctx = ctx->data;
if (!hctx->ktmp.data)
return 0;
hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
if (!hkey)
return 0;
EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
return 1;
}
static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
HMAC_PKEY_CTX *hctx = EVP_MD_CTX_pkey_ctx(ctx)->data;
if (!HMAC_Update(hctx->ctx, data, count))
return 0;
return 1;
}
static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
HMAC_PKEY_CTX *hctx = ctx->data;
HMAC_CTX_set_flags(hctx->ctx,
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);
return 1;
}
static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
EVP_MD_CTX *mctx)
{
unsigned int hlen;
HMAC_PKEY_CTX *hctx = ctx->data;
int l = EVP_MD_CTX_size(mctx);
if (l < 0)
return 0;
*siglen = l;
if (!sig)
return 1;
if (!HMAC_Final(hctx->ctx, sig, &hlen))
return 0;
*siglen = (size_t)hlen;
return 1;
}
static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
HMAC_PKEY_CTX *hctx = ctx->data;
ASN1_OCTET_STRING *key;
switch (type) {
case EVP_PKEY_CTRL_SET_MAC_KEY:
if ((!p2 && p1 > 0) || (p1 < -1))
return 0;
if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
return 0;
break;
case EVP_PKEY_CTRL_MD:
hctx->md = p2;
break;
case EVP_PKEY_CTRL_DIGESTINIT:
key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md,
ctx->engine))
return 0;
break;
default:
return -2;
}
return 1;
}
static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
if (!value) {
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 hmac_pkey_meth = {
EVP_PKEY_HMAC,
0,
pkey_hmac_init,
pkey_hmac_copy,
pkey_hmac_cleanup,
0, 0,
0,
pkey_hmac_keygen,
0, 0,
0, 0,
0, 0,
hmac_signctx_init,
hmac_signctx,
0, 0,
0, 0,
0, 0,
0, 0,
pkey_hmac_ctrl,
pkey_hmac_ctrl_str
};
+8
View File
@@ -41,5 +41,13 @@
__owur int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res,
const BIGNUM *x, BN_CTX *ctx);
/*-
* ECDH Key Derivation Function as defined in ANSI X9.63
*/
int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
const unsigned char *Z, size_t Zlen,
const unsigned char *sinfo, size_t sinfolen,
const EVP_MD *md);
# endif /* OPENSSL_NO_EC */
#endif
+30
View File
@@ -112,6 +112,35 @@ extern const EVP_PKEY_METHOD hkdf_pkey_meth;
extern const EVP_PKEY_METHOD poly1305_pkey_meth;
extern const EVP_PKEY_METHOD siphash_pkey_meth;
/* struct evp_mac_impl_st is defined by the implementation */
typedef struct evp_mac_impl_st EVP_MAC_IMPL;
struct evp_mac_st {
int type;
EVP_MAC_IMPL *(*new) (void);
int (*copy) (EVP_MAC_IMPL *macdst, EVP_MAC_IMPL *macsrc);
void (*free) (EVP_MAC_IMPL *macctx);
size_t (*size) (EVP_MAC_IMPL *macctx);
int (*init) (EVP_MAC_IMPL *macctx);
int (*update) (EVP_MAC_IMPL *macctx, const unsigned char *data,
size_t datalen);
int (*final) (EVP_MAC_IMPL *macctx, unsigned char *out);
int (*ctrl) (EVP_MAC_IMPL *macctx, int cmd, va_list args);
int (*ctrl_str) (EVP_MAC_IMPL *macctx, const char *type, const char *value);
};
extern const EVP_MAC cmac_meth;
extern const EVP_MAC hmac_meth;
extern const EVP_MAC siphash_meth;
/*
* This function is internal for now, but can be made external when needed.
* The documentation would read:
*
* EVP_add_mac() adds the MAC implementation C<mac> to the internal
* object database.
*/
int EVP_add_mac(const EVP_MAC *mac);
struct evp_md_st {
int type;
int pkey_type;
@@ -423,6 +452,7 @@ struct evp_pkey_st {
void openssl_add_all_ciphers_int(void);
void openssl_add_all_digests_int(void);
void openssl_add_all_macs_int(void);
void evp_cleanup_int(void);
void evp_app_cleanup_int(void);
+25
View File
@@ -235,6 +235,23 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
return 1;
}
static CRYPTO_ONCE add_all_macs = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_macs)
{
/*
* OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
* pulling in all the macs during static linking
*/
#ifndef OPENSSL_NO_AUTOALGINIT
# ifdef OPENSSL_INIT_DEBUG
fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_macs: "
"openssl_add_all_macs_int()\n");
# endif
openssl_add_all_macs_int();
#endif
return 1;
}
DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs)
{
/* Do nothing */
@@ -619,6 +636,14 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
&& !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
return 0;
if ((opts & OPENSSL_INIT_NO_ADD_ALL_MACS)
&& !RUN_ONCE(&add_all_macs, ossl_init_no_add_algs))
return 0;
if ((opts & OPENSSL_INIT_ADD_ALL_MACS)
&& !RUN_ONCE(&add_all_macs, ossl_init_add_all_macs))
return 0;
if ((opts & OPENSSL_INIT_ATFORK)
&& !openssl_init_fork_handlers())
return 0;
+13 -1
View File
@@ -175,6 +175,18 @@ static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
return -2;
}
static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx)
{
HKDF_PKEY_CTX *kctx = ctx->data;
OPENSSL_clear_free(kctx->key, kctx->key_len);
OPENSSL_clear_free(kctx->salt, kctx->salt_len);
OPENSSL_cleanse(kctx->info, kctx->info_len);
memset(kctx, 0, sizeof(*kctx));
return 1;
}
static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
size_t *keylen)
{
@@ -236,7 +248,7 @@ const EVP_PKEY_METHOD hkdf_pkey_meth = {
0, 0,
0,
pkey_hkdf_derive_init,
pkey_hkdf_derive,
pkey_hkdf_ctrl,
pkey_hkdf_ctrl_str
+102 -39
View File
@@ -374,6 +374,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
max_entropylen += drbg->max_noncelen;
}
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
if (drbg->reseed_next_counter) {
drbg->reseed_next_counter++;
if(!drbg->reseed_next_counter)
drbg->reseed_next_counter = 1;
}
if (drbg->get_entropy != NULL)
entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
min_entropylen, max_entropylen, 0);
@@ -401,27 +408,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
drbg->state = DRBG_READY;
drbg->reseed_gen_counter = 1;
drbg->reseed_time = time(NULL);
if (drbg->reseed_prop_counter > 0) {
if (drbg->parent == NULL)
drbg->reseed_prop_counter++;
else
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
}
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
end:
if (entropy != NULL && drbg->cleanup_entropy != NULL)
drbg->cleanup_entropy(drbg, entropy, entropylen);
if (nonce != NULL && drbg->cleanup_nonce != NULL)
drbg->cleanup_nonce(drbg, nonce, noncelen);
if (drbg->pool != NULL) {
if (drbg->state == DRBG_READY) {
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED);
drbg->state = DRBG_ERROR;
}
rand_pool_free(drbg->pool);
drbg->pool = NULL;
}
if (drbg->state == DRBG_READY)
return 1;
return 0;
@@ -498,6 +491,14 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
}
drbg->state = DRBG_ERROR;
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
if (drbg->reseed_next_counter) {
drbg->reseed_next_counter++;
if(!drbg->reseed_next_counter)
drbg->reseed_next_counter = 1;
}
if (drbg->get_entropy != NULL)
entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
drbg->min_entropylen,
@@ -515,12 +516,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
drbg->state = DRBG_READY;
drbg->reseed_gen_counter = 1;
drbg->reseed_time = time(NULL);
if (drbg->reseed_prop_counter > 0) {
if (drbg->parent == NULL)
drbg->reseed_prop_counter++;
else
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
}
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
end:
if (entropy != NULL && drbg->cleanup_entropy != NULL)
@@ -625,14 +621,8 @@ int rand_drbg_restart(RAND_DRBG *drbg,
}
}
/* check whether a given entropy pool was cleared properly during reseed */
if (drbg->pool != NULL) {
drbg->state = DRBG_ERROR;
RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR);
rand_pool_free(drbg->pool);
drbg->pool = NULL;
return 0;
}
rand_pool_free(drbg->pool);
drbg->pool = NULL;
return drbg->state == DRBG_READY;
}
@@ -691,8 +681,11 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|| now - drbg->reseed_time >= drbg->reseed_time_interval)
reseed_required = 1;
}
if (drbg->reseed_prop_counter > 0 && drbg->parent != NULL) {
if (drbg->reseed_prop_counter != drbg->parent->reseed_prop_counter)
if (drbg->parent != NULL) {
unsigned int reseed_counter = tsan_load(&drbg->reseed_prop_counter);
if (reseed_counter > 0
&& tsan_load(&drbg->parent->reseed_prop_counter)
!= reseed_counter)
reseed_required = 1;
}
@@ -764,7 +757,8 @@ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
RAND_DRBG_get_nonce_fn get_nonce,
RAND_DRBG_cleanup_nonce_fn cleanup_nonce)
{
if (drbg->state != DRBG_UNINITIALISED)
if (drbg->state != DRBG_UNINITIALISED
|| drbg->parent != NULL)
return 0;
drbg->get_entropy = get_entropy;
drbg->cleanup_entropy = cleanup_entropy;
@@ -942,7 +936,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type)
goto err;
/* enable seed propagation */
drbg->reseed_prop_counter = 1;
tsan_store(&drbg->reseed_prop_counter, 1);
/*
* Ignore instantiation error to support just-in-time instantiation.
@@ -1031,11 +1025,53 @@ static int drbg_bytes(unsigned char *out, int count)
return ret;
}
/*
* Calculates the minimum length of a full entropy buffer
* which is necessary to seed (i.e. instantiate) the DRBG
* successfully.
*
* NOTE: There is a copy of this function in drbgtest.c.
* If you change anything here, you need to update
* the copy accordingly.
*/
static size_t rand_drbg_seedlen(RAND_DRBG *drbg)
{
/*
* If no os entropy source is available then RAND_seed(buffer, bufsize)
* is expected to succeed if and only if the buffer length satisfies
* the following requirements, which follow from the calculations
* in RAND_DRBG_instantiate().
*/
size_t min_entropy = drbg->strength;
size_t min_entropylen = drbg->min_entropylen;
/*
* Extra entropy for the random nonce in the absence of a
* get_nonce callback, see comment in RAND_DRBG_instantiate().
*/
if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) {
min_entropy += drbg->strength / 2;
min_entropylen += drbg->min_noncelen;
}
/*
* Convert entropy requirement from bits to bytes
* (dividing by 8 without rounding upwards, because
* all entropy requirements are divisible by 8).
*/
min_entropy >>= 3;
/* Return a value that satisfies both requirements */
return min_entropy > min_entropylen ? min_entropy : min_entropylen;
}
/* Implements the default OpenSSL RAND_add() method */
static int drbg_add(const void *buf, int num, double randomness)
{
int ret = 0;
RAND_DRBG *drbg = RAND_DRBG_get0_master();
size_t buflen;
size_t seedlen;
if (drbg == NULL)
return 0;
@@ -1043,7 +1079,37 @@ static int drbg_add(const void *buf, int num, double randomness)
if (num < 0 || randomness < 0.0)
return 0;
if (randomness > (double)RAND_DRBG_STRENGTH) {
rand_drbg_lock(drbg);
seedlen = rand_drbg_seedlen(drbg);
buflen = (size_t)num;
if (buflen < seedlen || randomness < (double) seedlen) {
#if defined(OPENSSL_RAND_SEED_NONE)
/*
* If no os entropy source is available, a reseeding will fail
* inevitably. So we use a trick to mix the buffer contents into
* the DRBG state without forcing a reseeding: we generate a
* dummy random byte, using the buffer content as additional data.
* Note: This won't work with RAND_DRBG_FLAG_CTR_NO_DF.
*/
unsigned char dummy[1];
ret = RAND_DRBG_generate(drbg, dummy, sizeof(dummy), 0, buf, buflen);
rand_drbg_unlock(drbg);
return ret;
#else
/*
* If an os entropy source is avaible then we declare the buffer content
* as additional data by setting randomness to zero and trigger a regular
* reseeding.
*/
randomness = 0.0;
#endif
}
if (randomness > (double)seedlen) {
/*
* The purpose of this check is to bound |randomness| by a
* relatively small value in order to prevent an integer
@@ -1052,13 +1118,10 @@ static int drbg_add(const void *buf, int num, double randomness)
* not bits, so this value corresponds to eight times the
* security strength.
*/
randomness = (double)RAND_DRBG_STRENGTH;
randomness = (double)seedlen;
}
rand_drbg_lock(drbg);
ret = rand_drbg_restart(drbg, buf,
(size_t)(unsigned int)num,
(size_t)(8*randomness));
ret = rand_drbg_restart(drbg, buf, buflen, (size_t)(8 * randomness));
rand_drbg_unlock(drbg);
return ret;
+5 -1
View File
@@ -16,6 +16,9 @@
# include <openssl/hmac.h>
# include <openssl/ec.h>
# include <openssl/rand_drbg.h>
# include "internal/tsan_assist.h"
# include "internal/numbers.h"
/* How many times to read the TSC as a randomness source. */
# define TSC_READ_COUNT 4
@@ -256,7 +259,8 @@ struct rand_drbg_st {
* is added by RAND_add() or RAND_seed() will have an immediate effect on
* the output of RAND_bytes() resp. RAND_priv_bytes().
*/
unsigned int reseed_prop_counter;
TSAN_QUALIFIER unsigned int reseed_prop_counter;
unsigned int reseed_next_counter;
size_t seedlen;
DRBG_STATUS state;
+8 -3
View File
@@ -151,6 +151,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
pool->entropy_requested = entropy;
} else {
pool = rand_pool_new(entropy, min_len, max_len);
if (pool == NULL)
return 0;
}
if (drbg->parent) {
@@ -172,6 +174,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
prediction_resistance,
NULL, 0) != 0)
bytes = bytes_needed;
drbg->reseed_next_counter
= tsan_load(&drbg->parent->reseed_prop_counter);
rand_drbg_unlock(drbg->parent);
rand_pool_add_end(pool, bytes, 8 * bytes);
@@ -200,7 +204,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
}
err:
rand_pool_free(pool);
if (drbg->pool == NULL)
rand_pool_free(pool);
return ret;
}
@@ -213,8 +218,6 @@ void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
{
if (drbg->pool == NULL)
OPENSSL_secure_clear_free(out, outlen);
else
drbg->pool = NULL;
}
@@ -539,6 +542,8 @@ unsigned char *rand_pool_detach(RAND_POOL *pool)
{
unsigned char *ret = pool->buffer;
pool->buffer = NULL;
pool->len = 0;
pool->entropy = 0;
return ret;
}
+29 -9
View File
@@ -16,6 +16,7 @@
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include <openssl/rand_drbg.h>
#include <openssl/buffer.h>
#ifdef OPENSSL_SYS_VMS
@@ -48,7 +49,7 @@
# define S_ISREG(m) ((m) & S_IFREG)
# endif
#define RAND_FILE_SIZE 1024
#define RAND_BUF_SIZE 1024
#define RFILE ".rnd"
#ifdef OPENSSL_SYS_VMS
@@ -74,7 +75,16 @@ static __FILE_ptr32 (*const vms_fopen)(const char *, const char *, ...) =
*/
int RAND_load_file(const char *file, long bytes)
{
unsigned char buf[RAND_FILE_SIZE];
/*
* The load buffer size exceeds the chunk size by the comfortable amount
* of 'RAND_DRBG_STRENGTH' bytes (not bits!). This is done on purpose
* to avoid calling RAND_add() with a small final chunk. Instead, such
* a small final chunk will be added together with the previous chunk
* (unless it's the only one).
*/
#define RAND_LOAD_BUF_SIZE (RAND_BUF_SIZE + RAND_DRBG_STRENGTH)
unsigned char buf[RAND_LOAD_BUF_SIZE];
#ifndef OPENSSL_NO_POSIX_IO
struct stat sb;
#endif
@@ -98,8 +108,12 @@ int RAND_load_file(const char *file, long bytes)
return -1;
}
if (!S_ISREG(sb.st_mode) && bytes < 0)
bytes = 256;
if (bytes < 0) {
if (S_ISREG(sb.st_mode))
bytes = sb.st_size;
else
bytes = RAND_DRBG_STRENGTH;
}
#endif
/*
* On VMS, setbuf() will only take 32-bit pointers, and a compilation
@@ -124,9 +138,9 @@ int RAND_load_file(const char *file, long bytes)
for ( ; ; ) {
if (bytes > 0)
n = (bytes < RAND_FILE_SIZE) ? (int)bytes : RAND_FILE_SIZE;
n = (bytes <= RAND_LOAD_BUF_SIZE) ? (int)bytes : RAND_BUF_SIZE;
else
n = RAND_FILE_SIZE;
n = RAND_LOAD_BUF_SIZE;
i = fread(buf, 1, n, in);
#ifdef EINTR
if (ferror(in) && errno == EINTR){
@@ -148,12 +162,18 @@ int RAND_load_file(const char *file, long bytes)
OPENSSL_cleanse(buf, sizeof(buf));
fclose(in);
if (!RAND_status()) {
RANDerr(RAND_F_RAND_LOAD_FILE, RAND_R_RESEED_ERROR);
ERR_add_error_data(2, "Filename=", file);
return -1;
}
return ret;
}
int RAND_write_file(const char *file)
{
unsigned char buf[RAND_FILE_SIZE];
unsigned char buf[RAND_BUF_SIZE];
int ret = -1;
FILE *out = NULL;
#ifndef OPENSSL_NO_POSIX_IO
@@ -222,9 +242,9 @@ int RAND_write_file(const char *file)
chmod(file, 0600);
#endif
ret = fwrite(buf, 1, RAND_FILE_SIZE, out);
ret = fwrite(buf, 1, RAND_BUF_SIZE, out);
fclose(out);
OPENSSL_cleanse(buf, RAND_FILE_SIZE);
OPENSSL_cleanse(buf, RAND_BUF_SIZE);
return ret;
}
+128 -1
View File
@@ -163,6 +163,133 @@ void *RSA_get_ex_data(const RSA *r, int idx)
return CRYPTO_get_ex_data(&r->ex_data, idx);
}
/*
* Define a scaling constant for our fixed point arithmetic.
* This value must be a power of two because the base two logarithm code
* makes this assumption. The exponent must also be a multiple of three so
* that the scale factor has an exact cube root. Finally, the scale factor
* should not be so large that a multiplication of two scaled numbers
* overflows a 64 bit unsigned integer.
*/
static const unsigned int scale = 1 << 18;
static const unsigned int cbrt_scale = 1 << (2 * 18 / 3);
/* Define some constants, none exceed 32 bits */
static const unsigned int log_2 = 0x02c5c8; /* scale * log(2) */
static const unsigned int log_e = 0x05c551; /* scale * log2(M_E) */
static const unsigned int c1_923 = 0x07b126; /* scale * 1.923 */
static const unsigned int c4_690 = 0x12c28f; /* scale * 4.690 */
/*
* Multiply two scale integers together and rescale the result.
*/
static ossl_inline uint64_t mul2(uint64_t a, uint64_t b)
{
return a * b / scale;
}
/*
* Calculate the cube root of a 64 bit scaled integer.
* Although the cube root of a 64 bit number does fit into a 32 bit unsigned
* integer, this is not guaranteed after scaling, so this function has a
* 64 bit return. This uses the shifting nth root algorithm with some
* algebraic simplifications.
*/
static uint64_t icbrt64(uint64_t x)
{
uint64_t r = 0;
uint64_t b;
int s;
for (s = 63; s >= 0; s -= 3) {
r <<= 1;
b = 3 * r * (r + 1) + 1;
if ((x >> s) >= b) {
x -= b << s;
r++;
}
}
return r * cbrt_scale;
}
/*
* Calculate the natural logarithm of a 64 bit scaled integer.
* This is done by calculating a base two logarithm and scaling.
* The maximum logarithm (base 2) is 64 and this reduces base e, so
* a 32 bit result should not overflow. The argument passed must be
* greater than unity so we don't need to handle negative results.
*/
static uint32_t ilog_e(uint64_t v)
{
uint32_t i, r = 0;
/*
* Scale down the value into the range 1 .. 2.
*
* If fractional numbers need to be processed, another loop needs
* to go here that checks v < scale and if so multiplies it by 2 and
* reduces r by scale. This also means making r signed.
*/
while (v >= 2 * scale) {
v >>= 1;
r += scale;
}
for (i = scale / 2; i != 0; i /= 2) {
v = mul2(v, v);
if (v >= 2 * scale) {
v >>= 1;
r += i;
}
}
r = (r * (uint64_t)scale) / log_e;
return r;
}
/*
* NIST SP 800-56B rev 2 Appendix D: Maximum Security Strength Estimates for IFC
* Modulus Lengths.
*
* E = \frac{1.923 \sqrt[3]{nBits \cdot log_e(2)}
* \cdot(log_e(nBits \cdot log_e(2))^{2/3} - 4.69}{log_e(2)}
* The two cube roots are merged together here.
*/
static uint16_t rsa_compute_security_bits(int n)
{
uint64_t x;
uint32_t lx;
uint16_t y;
/* Look for common values as listed in SP 800-56B rev 2 Appendix D */
switch (n) {
case 2048:
return 112;
case 3072:
return 128;
case 4096:
return 152;
case 6144:
return 176;
case 8192:
return 200;
}
/*
* The first incorrect result (i.e. not accurate or off by one low) occurs
* for n = 699668. The true value here is 1200. Instead of using this n
* as the check threshold, the smallest n such that the correct result is
* 1200 is used instead.
*/
if (n >= 687737)
return 1200;
if (n < 8)
return 0;
x = n * (uint64_t)log_2;
lx = ilog_e(x);
y = (uint16_t)((mul2(c1_923, icbrt64(mul2(mul2(x, lx), lx))) - c4_690)
/ log_2);
return (y + 4) & ~7;
}
int RSA_security_bits(const RSA *rsa)
{
int bits = BN_num_bits(rsa->n);
@@ -174,7 +301,7 @@ int RSA_security_bits(const RSA *rsa)
if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits))
return 0;
}
return BN_security_bits(bits, -1);
return rsa_compute_security_bits(bits);
}
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+20 -3
View File
@@ -49,6 +49,9 @@ struct OPENSSL_s390xcap_st {
extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
/* Max number of 64-bit words currently returned by STFLE */
# define S390X_STFLE_MAX 3
/* convert facility bit number or function code to bit mask */
# define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64))
@@ -68,9 +71,15 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
# define S390X_KMA 0xb0
/* Facility Bit Numbers */
# define S390X_VX 129
# define S390X_VXD 134
# define S390X_VXE 135
# define S390X_MSA 17 /* message-security-assist */
# define S390X_STCKF 25 /* store-clock-fast */
# define S390X_MSA5 57 /* message-security-assist-ext. 5 */
# define S390X_MSA3 76 /* message-security-assist-ext. 3 */
# define S390X_MSA4 77 /* message-security-assist-ext. 4 */
# define S390X_VX 129 /* vector */
# define S390X_VXD 134 /* vector packed decimal */
# define S390X_VXE 135 /* vector enhancements 1 */
# define S390X_MSA8 146 /* message-security-assist-ext. 8 */
/* Function Codes */
@@ -78,6 +87,9 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
# define S390X_QUERY 0
/* kimd/klmd */
# define S390X_SHA_1 1
# define S390X_SHA_256 2
# define S390X_SHA_512 3
# define S390X_SHA3_224 32
# define S390X_SHA3_256 33
# define S390X_SHA3_384 34
@@ -91,7 +103,12 @@ extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
# define S390X_AES_192 19
# define S390X_AES_256 20
/* km */
# define S390X_XTS_AES_128 50
# define S390X_XTS_AES_256 52
/* prno */
# define S390X_SHA_512_DRNG 3
# define S390X_TRNG 114
/* Register 0 Flags */
+515
View File
@@ -13,15 +13,51 @@
#include <setjmp.h>
#include <signal.h>
#include "internal/cryptlib.h"
#include "internal/ctype.h"
#include "s390x_arch.h"
#define LEN 128
#define STR_(S) #S
#define STR(S) STR_(S)
#define TOK_FUNC(NAME) \
(sscanf(tok_begin, \
" " STR(NAME) " : %" STR(LEN) "[^:] : " \
"%" STR(LEN) "s %" STR(LEN) "s ", \
tok[0], tok[1], tok[2]) == 2) { \
\
off = (tok[0][0] == '~') ? 1 : 0; \
if (sscanf(tok[0] + off, "%llx", &cap->NAME[0]) != 1) \
goto ret; \
if (off) \
cap->NAME[0] = ~cap->NAME[0]; \
\
off = (tok[1][0] == '~') ? 1 : 0; \
if (sscanf(tok[1] + off, "%llx", &cap->NAME[1]) != 1) \
goto ret; \
if (off) \
cap->NAME[1] = ~cap->NAME[1]; \
}
#define TOK_CPU(NAME) \
(sscanf(tok_begin, \
" %" STR(LEN) "s %" STR(LEN) "s ", \
tok[0], tok[1]) == 1 \
&& !strcmp(tok[0], #NAME)) { \
memcpy(cap, &NAME, sizeof(*cap)); \
}
static sigjmp_buf ill_jmp;
static void ill_handler(int sig)
{
siglongjmp(ill_jmp, sig);
}
static const char *env;
static int parse_env(struct OPENSSL_s390xcap_st *cap);
void OPENSSL_s390x_facilities(void);
void OPENSSL_s390x_functions(void);
void OPENSSL_vx_probe(void);
struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
@@ -30,6 +66,7 @@ void OPENSSL_cpuid_setup(void)
{
sigset_t oset;
struct sigaction ill_act, oact;
struct OPENSSL_s390xcap_st cap;
if (OPENSSL_s390xcap_P.stfle[0])
return;
@@ -37,6 +74,12 @@ void OPENSSL_cpuid_setup(void)
/* set a bit that will not be tested later */
OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0);
env = getenv("OPENSSL_s390xcap");
if (env != NULL) {
if (!parse_env(&cap))
env = NULL;
}
memset(&ill_act, 0, sizeof(ill_act));
ill_act.sa_handler = ill_handler;
sigfillset(&ill_act.sa_mask);
@@ -51,6 +94,12 @@ void OPENSSL_cpuid_setup(void)
if (sigsetjmp(ill_jmp, 1) == 0)
OPENSSL_s390x_facilities();
if (env != NULL) {
OPENSSL_s390xcap_P.stfle[0] &= cap.stfle[0];
OPENSSL_s390xcap_P.stfle[1] &= cap.stfle[1];
OPENSSL_s390xcap_P.stfle[2] &= cap.stfle[2];
}
/* protection against disabled vector facility */
if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX))
&& (sigsetjmp(ill_jmp, 1) == 0)) {
@@ -64,4 +113,470 @@ void OPENSSL_cpuid_setup(void)
sigaction(SIGFPE, &oact, NULL);
sigaction(SIGILL, &oact, NULL);
sigprocmask(SIG_SETMASK, &oset, NULL);
OPENSSL_s390x_functions();
if (env != NULL) {
OPENSSL_s390xcap_P.kimd[0] &= cap.kimd[0];
OPENSSL_s390xcap_P.kimd[1] &= cap.kimd[1];
OPENSSL_s390xcap_P.klmd[0] &= cap.klmd[0];
OPENSSL_s390xcap_P.klmd[1] &= cap.klmd[1];
OPENSSL_s390xcap_P.km[0] &= cap.km[0];
OPENSSL_s390xcap_P.km[1] &= cap.km[1];
OPENSSL_s390xcap_P.kmc[0] &= cap.kmc[0];
OPENSSL_s390xcap_P.kmc[1] &= cap.kmc[1];
OPENSSL_s390xcap_P.kmac[0] &= cap.kmac[0];
OPENSSL_s390xcap_P.kmac[1] &= cap.kmac[1];
OPENSSL_s390xcap_P.kmctr[0] &= cap.kmctr[0];
OPENSSL_s390xcap_P.kmctr[1] &= cap.kmctr[1];
OPENSSL_s390xcap_P.kmo[0] &= cap.kmo[0];
OPENSSL_s390xcap_P.kmo[1] &= cap.kmo[1];
OPENSSL_s390xcap_P.kmf[0] &= cap.kmf[0];
OPENSSL_s390xcap_P.kmf[1] &= cap.kmf[1];
OPENSSL_s390xcap_P.prno[0] &= cap.prno[0];
OPENSSL_s390xcap_P.prno[1] &= cap.prno[1];
OPENSSL_s390xcap_P.kma[0] &= cap.kma[0];
OPENSSL_s390xcap_P.kma[1] &= cap.kma[1];
}
}
static int parse_env(struct OPENSSL_s390xcap_st *cap)
{
/*-
* CPU model data
* (only the STFLE- and QUERY-bits relevant to libcrypto are set)
*/
/*-
* z900 (2000) - z/Architecture POP SA22-7832-00
* Facility detection would fail on real hw (no STFLE).
*/
static const struct OPENSSL_s390xcap_st z900 = {
.stfle = {0ULL, 0ULL, 0ULL, 0ULL},
.kimd = {0ULL, 0ULL},
.klmd = {0ULL, 0ULL},
.km = {0ULL, 0ULL},
.kmc = {0ULL, 0ULL},
.kmac = {0ULL, 0ULL},
.kmctr = {0ULL, 0ULL},
.kmo = {0ULL, 0ULL},
.kmf = {0ULL, 0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z990 (2003) - z/Architecture POP SA22-7832-02
* Implements MSA. Facility detection would fail on real hw (no STFLE).
*/
static const struct OPENSSL_s390xcap_st z990 = {
.stfle = {S390X_CAPBIT(S390X_MSA),
0ULL, 0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1),
0ULL},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmctr = {0ULL, 0ULL},
.kmo = {0ULL, 0ULL},
.kmf = {0ULL, 0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z9 (2005) - z/Architecture POP SA22-7832-04
* Implements MSA and MSA1.
*/
static const struct OPENSSL_s390xcap_st z9 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF),
0ULL, 0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256),
0ULL},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmctr = {0ULL, 0ULL},
.kmo = {0ULL, 0ULL},
.kmf = {0ULL, 0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z10 (2008) - z/Architecture POP SA22-7832-06
* Implements MSA and MSA1-2.
*/
static const struct OPENSSL_s390xcap_st z10 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF),
0ULL, 0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY),
0ULL},
.kmctr = {0ULL, 0ULL},
.kmo = {0ULL, 0ULL},
.kmf = {0ULL, 0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z196 (2010) - z/Architecture POP SA22-7832-08
* Implements MSA and MSA1-4.
*/
static const struct OPENSSL_s390xcap_st z196 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF),
S390X_CAPBIT(S390X_MSA3)
| S390X_CAPBIT(S390X_MSA4),
0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
S390X_CAPBIT(S390X_GHASH)},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256)
| S390X_CAPBIT(S390X_XTS_AES_128)
| S390X_CAPBIT(S390X_XTS_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmctr = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmo = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmf = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* zEC12 (2012) - z/Architecture POP SA22-7832-09
* Implements MSA and MSA1-4.
*/
static const struct OPENSSL_s390xcap_st zEC12 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF),
S390X_CAPBIT(S390X_MSA3)
| S390X_CAPBIT(S390X_MSA4),
0ULL, 0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
S390X_CAPBIT(S390X_GHASH)},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256)
| S390X_CAPBIT(S390X_XTS_AES_128)
| S390X_CAPBIT(S390X_XTS_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmctr = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmo = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmf = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.prno = {0ULL, 0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z13 (2015) - z/Architecture POP SA22-7832-10
* Implements MSA and MSA1-5.
*/
static const struct OPENSSL_s390xcap_st z13 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF)
| S390X_CAPBIT(S390X_MSA5),
S390X_CAPBIT(S390X_MSA3)
| S390X_CAPBIT(S390X_MSA4),
S390X_CAPBIT(S390X_VX),
0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
S390X_CAPBIT(S390X_GHASH)},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256)
| S390X_CAPBIT(S390X_XTS_AES_128)
| S390X_CAPBIT(S390X_XTS_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmctr = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmo = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmf = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.prno = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_512_DRNG),
0ULL},
.kma = {0ULL, 0ULL},
};
/*-
* z14 (2017) - z/Architecture POP SA22-7832-11
* Implements MSA and MSA1-8.
*/
static const struct OPENSSL_s390xcap_st z14 = {
.stfle = {S390X_CAPBIT(S390X_MSA)
| S390X_CAPBIT(S390X_STCKF)
| S390X_CAPBIT(S390X_MSA5),
S390X_CAPBIT(S390X_MSA3)
| S390X_CAPBIT(S390X_MSA4),
S390X_CAPBIT(S390X_VX)
| S390X_CAPBIT(S390X_VXD)
| S390X_CAPBIT(S390X_VXE)
| S390X_CAPBIT(S390X_MSA8),
0ULL},
.kimd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512)
| S390X_CAPBIT(S390X_SHA3_224)
| S390X_CAPBIT(S390X_SHA3_256)
| S390X_CAPBIT(S390X_SHA3_384)
| S390X_CAPBIT(S390X_SHA3_512)
| S390X_CAPBIT(S390X_SHAKE_128)
| S390X_CAPBIT(S390X_SHAKE_256),
S390X_CAPBIT(S390X_GHASH)},
.klmd = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_1)
| S390X_CAPBIT(S390X_SHA_256)
| S390X_CAPBIT(S390X_SHA_512)
| S390X_CAPBIT(S390X_SHA3_224)
| S390X_CAPBIT(S390X_SHA3_256)
| S390X_CAPBIT(S390X_SHA3_384)
| S390X_CAPBIT(S390X_SHA3_512)
| S390X_CAPBIT(S390X_SHAKE_128)
| S390X_CAPBIT(S390X_SHAKE_256),
0ULL},
.km = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256)
| S390X_CAPBIT(S390X_XTS_AES_128)
| S390X_CAPBIT(S390X_XTS_AES_256),
0ULL},
.kmc = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmac = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmctr = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmo = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.kmf = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
.prno = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_SHA_512_DRNG),
S390X_CAPBIT(S390X_TRNG)},
.kma = {S390X_CAPBIT(S390X_QUERY)
| S390X_CAPBIT(S390X_AES_128)
| S390X_CAPBIT(S390X_AES_192)
| S390X_CAPBIT(S390X_AES_256),
0ULL},
};
char *tok_begin, *tok_end, *buff, tok[S390X_STFLE_MAX][LEN + 1];
int rc, off, i, n;
buff = malloc(strlen(env) + 1);
if (buff == NULL)
return 0;
rc = 0;
memset(cap, ~0, sizeof(*cap));
strcpy(buff, env);
tok_begin = buff + strspn(buff, ";");
strtok(tok_begin, ";");
tok_end = strtok(NULL, ";");
while (tok_begin != NULL) {
/* stfle token */
if ((n = sscanf(tok_begin,
" stfle : %" STR(LEN) "[^:] : "
"%" STR(LEN) "[^:] : %" STR(LEN) "s ",
tok[0], tok[1], tok[2]))) {
for (i = 0; i < n; i++) {
off = (tok[i][0] == '~') ? 1 : 0;
if (sscanf(tok[i] + off, "%llx", &cap->stfle[i]) != 1)
goto ret;
if (off)
cap->stfle[i] = ~cap->stfle[i];
}
}
/* query function tokens */
else if TOK_FUNC(kimd)
else if TOK_FUNC(klmd)
else if TOK_FUNC(km)
else if TOK_FUNC(kmc)
else if TOK_FUNC(kmac)
else if TOK_FUNC(kmctr)
else if TOK_FUNC(kmo)
else if TOK_FUNC(kmf)
else if TOK_FUNC(prno)
else if TOK_FUNC(kma)
/* CPU model tokens */
else if TOK_CPU(z900)
else if TOK_CPU(z990)
else if TOK_CPU(z9)
else if TOK_CPU(z10)
else if TOK_CPU(z196)
else if TOK_CPU(zEC12)
else if TOK_CPU(z13)
else if TOK_CPU(z14)
/* whitespace(ignored) or invalid tokens */
else {
while (*tok_begin != '\0') {
if (!ossl_isspace(*tok_begin))
goto ret;
tok_begin++;
}
}
tok_begin = tok_end;
tok_end = strtok(NULL, ";");
}
rc = 1;
ret:
free(buff);
return rc;
}
+21 -10
View File
@@ -38,7 +38,26 @@ OPENSSL_s390x_facilities:
stg %r0,S390X_STFLE+8(%r4) # wipe capability vectors
stg %r0,S390X_STFLE+16(%r4)
stg %r0,S390X_STFLE+24(%r4)
stg %r0,S390X_KIMD(%r4)
.long 0xb2b04000 # stfle 0(%r4)
brc 8,.Ldone
lghi %r0,1
.long 0xb2b04000 # stfle 0(%r4)
brc 8,.Ldone
lghi %r0,2
.long 0xb2b04000 # stfle 0(%r4)
.Ldone:
br $ra
.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
.globl OPENSSL_s390x_functions
.type OPENSSL_s390x_functions,\@function
.align 16
OPENSSL_s390x_functions:
lghi %r0,0
larl %r4,OPENSSL_s390xcap_P
stg %r0,S390X_KIMD(%r4) # wipe capability vectors
stg %r0,S390X_KIMD+8(%r4)
stg %r0,S390X_KLMD(%r4)
stg %r0,S390X_KLMD+8(%r4)
@@ -59,14 +78,6 @@ OPENSSL_s390x_facilities:
stg %r0,S390X_KMA(%r4)
stg %r0,S390X_KMA+8(%r4)
.long 0xb2b04000 # stfle 0(%r4)
brc 8,.Ldone
lghi %r0,1
.long 0xb2b04000 # stfle 0(%r4)
brc 8,.Ldone
lghi %r0,2
.long 0xb2b04000 # stfle 0(%r4)
.Ldone:
lmg %r2,%r3,S390X_STFLE(%r4)
tmhl %r2,0x4000 # check for message-security-assist
jz .Lret
@@ -123,7 +134,7 @@ OPENSSL_s390x_facilities:
.Lret:
br $ra
.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
.size OPENSSL_s390x_functions,.-OPENSSL_s390x_functions
.globl OPENSSL_rdtsc
.type OPENSSL_rdtsc,\@function
+71 -79
View File
@@ -533,30 +533,28 @@ my @A = map([ "v".$_.".16b", "v".($_+1).".16b", "v".($_+2).".16b",
(0, 5, 10, 15, 20));
my @C = map("v$_.16b", (25..31));
my @D = @C[4,5,6,2,3];
$code.=<<___;
.type KeccakF1600_ce,%function
.align 5
KeccakF1600_ce:
mov x9,#12
mov x9,#24
adr x10,iotas
b .Loop_ce
.align 4
.Loop_ce:
___
for($i=0; $i<2; $i++) {
$code.=<<___;
////////////////////////////////////////////////// Theta
eor3 $C[0],$A[0][0],$A[1][0],$A[2][0]
eor3 $C[1],$A[0][1],$A[1][1],$A[2][1]
eor3 $C[2],$A[0][2],$A[1][2],$A[2][2]
eor3 $C[3],$A[0][3],$A[1][3],$A[2][3]
eor3 $C[4],$A[0][4],$A[1][4],$A[2][4]
eor3 $C[0],$C[0], $A[3][0],$A[4][0]
eor3 $C[1],$C[1], $A[3][1],$A[4][1]
eor3 $C[2],$C[2], $A[3][2],$A[4][2]
eor3 $C[3],$C[3], $A[3][3],$A[4][3]
eor3 $C[4],$C[4], $A[3][4],$A[4][4]
eor3 $C[0],$A[4][0],$A[3][0],$A[2][0]
eor3 $C[1],$A[4][1],$A[3][1],$A[2][1]
eor3 $C[2],$A[4][2],$A[3][2],$A[2][2]
eor3 $C[3],$A[4][3],$A[3][3],$A[2][3]
eor3 $C[4],$A[4][4],$A[3][4],$A[2][4]
eor3 $C[0],$C[0], $A[1][0],$A[0][0]
eor3 $C[1],$C[1], $A[1][1],$A[0][1]
eor3 $C[2],$C[2], $A[1][2],$A[0][2]
eor3 $C[3],$C[3], $A[1][3],$A[0][3]
eor3 $C[4],$C[4], $A[1][4],$A[0][4]
rax1 $C[5],$C[0],$C[2] // D[1]
rax1 $C[6],$C[1],$C[3] // D[2]
@@ -565,81 +563,75 @@ $code.=<<___;
rax1 $C[4],$C[4],$C[1] // D[0]
////////////////////////////////////////////////// Theta+Rho+Pi
xar $C[0], $A[1][1],$C[5],#64-$rhotates[1][1] // C[0]=A[0][1]
xar $A[1][1],$A[1][4],$C[3],#64-$rhotates[1][4]
xar $A[1][4],$A[4][2],$C[6],#64-$rhotates[4][2]
xar $A[4][2],$A[2][4],$C[3],#64-$rhotates[2][4]
xar $A[2][4],$A[4][0],$C[4],#64-$rhotates[4][0]
xar $C[0], $A[0][1],$D[1],#64-$rhotates[0][1] // C[0]=A[2][0]
xar $A[4][0],$A[0][2],$C[6],#64-$rhotates[0][2]
xar $A[0][1],$A[1][1],$D[1],#64-$rhotates[1][1]
xar $A[1][1],$A[1][4],$D[4],#64-$rhotates[1][4]
xar $A[1][4],$A[4][2],$D[2],#64-$rhotates[4][2]
xar $A[4][2],$A[2][4],$D[4],#64-$rhotates[2][4]
xar $A[2][4],$A[4][0],$D[0],#64-$rhotates[4][0]
xar $A[0][2],$A[2][2],$C[6],#64-$rhotates[2][2]
xar $A[2][2],$A[2][3],$C[2],#64-$rhotates[2][3]
xar $A[2][3],$A[3][4],$C[3],#64-$rhotates[3][4]
xar $A[3][4],$A[4][3],$C[2],#64-$rhotates[4][3]
xar $A[4][3],$A[3][0],$C[4],#64-$rhotates[3][0]
xar $C[1], $A[0][2],$D[2],#64-$rhotates[0][2] // C[1]=A[4][0]
xar $A[3][0],$A[0][4],$C[3],#64-$rhotates[0][4]
xar $A[0][2],$A[2][2],$D[2],#64-$rhotates[2][2]
xar $A[2][2],$A[2][3],$D[3],#64-$rhotates[2][3]
xar $A[2][3],$A[3][4],$D[4],#64-$rhotates[3][4]
xar $A[3][4],$A[4][3],$D[3],#64-$rhotates[4][3]
xar $A[4][3],$A[3][0],$D[0],#64-$rhotates[3][0]
eor $A[0][0],$A[0][0],$C[4]
ldr x11,[x10],#8
xar $A[3][0],$A[0][4],$D[4],#64-$rhotates[0][4]
xar $C[1], $A[3][3],$C[2],#64-$rhotates[3][3] // C[1]=A[0][3]
xar $A[3][3],$A[3][2],$C[6],#64-$rhotates[3][2]
xar $A[3][2],$A[2][1],$C[5],#64-$rhotates[2][1]
xar $A[2][1],$A[1][2],$C[6],#64-$rhotates[1][2]
xar $A[1][2],$A[2][0],$C[4],#64-$rhotates[2][0]
xar $D[4], $A[4][4],$D[4],#64-$rhotates[4][4] // D[4]=A[0][4]
xar $A[4][4],$A[4][1],$D[1],#64-$rhotates[4][1]
xar $A[1][3],$A[1][3],$D[3],#64-$rhotates[1][3] // A[1][3]=A[4][1]
xar $A[0][4],$A[3][1],$D[1],#64-$rhotates[3][1] // A[0][4]=A[1][3]
xar $A[3][1],$A[1][0],$D[0],#64-$rhotates[1][0]
xar $A[2][0],$A[0][1],$C[5],#64-$rhotates[0][1] // *
xar $A[1][0],$A[0][3],$D[3],#64-$rhotates[0][3]
xar $A[0][4],$A[4][4],$C[3],#64-$rhotates[4][4]
xar $A[4][4],$A[4][1],$C[5],#64-$rhotates[4][1]
xar $A[4][1],$A[1][3],$C[2],#64-$rhotates[1][3]
xar $A[1][3],$A[3][1],$C[5],#64-$rhotates[3][1]
xar $A[3][1],$A[1][0],$C[4],#64-$rhotates[1][0]
eor $A[0][0],$A[0][0],$D[0]
xar $C[2], $A[0][3],$C[2],#64-$rhotates[0][3] // C[2]=A[1][0]
xar $D[3], $A[3][3],$D[3],#64-$rhotates[3][3] // D[3]=A[0][3]
xar $A[0][3],$A[3][2],$D[2],#64-$rhotates[3][2] // A[0][3]=A[3][3]
xar $D[1], $A[2][1],$D[1],#64-$rhotates[2][1] // D[1]=A[3][2]
xar $D[2], $A[1][2],$D[2],#64-$rhotates[1][2] // D[2]=A[2][1]
xar $D[0], $A[2][0],$D[0],#64-$rhotates[2][0] // D[0]=A[1][2]
////////////////////////////////////////////////// Chi+Iota
dup $C[6],x11 // borrow C[6]
bcax $C[3], $A[0][0],$A[0][2],$C[0] // *
bcax $A[0][1],$C[0], $C[1], $A[0][2] // *
bcax $A[0][2],$A[0][2],$A[0][4],$C[1]
bcax $A[0][3],$C[1], $A[0][0],$A[0][4]
bcax $A[0][4],$A[0][4],$C[0], $A[0][0]
bcax $A[1][0],$C[2], $A[1][2],$A[1][1] // *
bcax $C[0], $A[1][1],$A[1][3],$A[1][2] // *
bcax $A[1][2],$A[1][2],$A[1][4],$A[1][3]
bcax $A[1][3],$A[1][3],$C[2], $A[1][4]
bcax $A[1][4],$A[1][4],$A[1][1],$C[2]
eor $A[0][0],$C[3],$C[6] // Iota
bcax $C[1], $A[2][0],$A[2][2],$A[2][1] // *
bcax $C[2], $A[2][1],$A[2][3],$A[2][2] // *
bcax $A[2][2],$A[2][2],$A[2][4],$A[2][3]
bcax $A[2][3],$A[2][3],$A[2][0],$A[2][4]
bcax $A[2][4],$A[2][4],$A[2][1],$A[2][0]
bcax $C[3], $A[3][0],$A[3][2],$A[3][1] // *
bcax $C[4], $A[3][1],$A[3][3],$A[3][2] // *
bcax $A[3][2],$A[3][2],$A[3][4],$A[3][3]
bcax $A[3][3],$A[3][3],$A[3][0],$A[3][4]
bcax $A[3][4],$A[3][4],$A[3][1],$A[3][0]
bcax $C[5], $A[4][0],$A[4][2],$A[4][1] // *
bcax $C[6], $A[4][1],$A[4][3],$A[4][2] // *
bcax $A[4][0],$C[1], $A[4][2],$A[1][3] // A[1][3]=A[4][1]
bcax $A[4][1],$A[1][3],$A[4][3],$A[4][2] // A[1][3]=A[4][1]
bcax $A[4][2],$A[4][2],$A[4][4],$A[4][3]
bcax $A[4][3],$A[4][3],$A[4][0],$A[4][4]
bcax $A[4][4],$A[4][4],$A[4][1],$A[4][0]
___
( $A[1][1], $C[0]) = ( $C[0], $A[1][1]);
($A[2][0],$A[2][1], $C[1],$C[2]) = ($C[1],$C[2], $A[2][0],$A[2][1]);
($A[3][0],$A[3][1], $C[3],$C[4]) = ($C[3],$C[4], $A[3][0],$A[3][1]);
($A[4][0],$A[4][1], $C[5],$C[6]) = ($C[5],$C[6], $A[4][0],$A[4][1]);
}
$code.=<<___;
bcax $A[4][3],$A[4][3],$C[1], $A[4][4]
bcax $A[4][4],$A[4][4],$A[1][3],$C[1] // A[1][3]=A[4][1]
ld1r {$C[1]},[x10],#8
bcax $A[3][2],$D[1], $A[3][4],$A[0][3] // A[0][3]=A[3][3]
bcax $A[3][3],$A[0][3],$A[3][0],$A[3][4] // A[0][3]=A[3][3]
bcax $A[3][4],$A[3][4],$A[3][1],$A[3][0]
bcax $A[3][0],$A[3][0],$D[1], $A[3][1]
bcax $A[3][1],$A[3][1],$A[0][3],$D[1] // A[0][3]=A[3][3]
bcax $A[2][0],$C[0], $A[2][2],$D[2]
bcax $A[2][1],$D[2], $A[2][3],$A[2][2]
bcax $A[2][2],$A[2][2],$A[2][4],$A[2][3]
bcax $A[2][3],$A[2][3],$C[0], $A[2][4]
bcax $A[2][4],$A[2][4],$D[2], $C[0]
bcax $A[1][2],$D[0], $A[1][4],$A[0][4] // A[0][4]=A[1][3]
bcax $A[1][3],$A[0][4],$A[1][0],$A[1][4] // A[0][4]=A[1][3]
bcax $A[1][4],$A[1][4],$A[1][1],$A[1][0]
bcax $A[1][0],$A[1][0],$D[0], $A[1][1]
bcax $A[1][1],$A[1][1],$A[0][4],$D[0] // A[0][4]=A[1][3]
bcax $A[0][3],$D[3], $A[0][0],$D[4]
bcax $A[0][4],$D[4], $A[0][1],$A[0][0]
bcax $A[0][0],$A[0][0],$A[0][2],$A[0][1]
bcax $A[0][1],$A[0][1],$D[3], $A[0][2]
bcax $A[0][2],$A[0][2],$D[4], $D[3]
eor $A[0][0],$A[0][0],$C[1]
subs x9,x9,#1
bne .Loop_ce
@@ -857,7 +849,7 @@ foreach(split("\n",$code)) {
s/\`([^\`]*)\`/eval($1)/ge;
m/\bdup\b/ and s/\.16b/.2d/g or
m/\bld1r\b/ and s/\.16b/.2d/g or
s/\b(eor3|rax1|xar|bcax)\s+(v.*)/unsha3($1,$2)/ge;
print $_,"\n";
+1 -1
View File
@@ -1,5 +1,5 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
siphash.c \
siphash_pmeth.c \
siphash_meth.c \
siphash_ameth.c
+139
View File
@@ -0,0 +1,139 @@
/*
* 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
*/
#include <stdarg.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include "internal/siphash.h"
#include "siphash_local.h"
#include "internal/evp_int.h"
/* local SIPHASH structure is actually a SIPHASH */
struct evp_mac_impl_st {
SIPHASH ctx;
};
static EVP_MAC_IMPL *siphash_new(void)
{
return OPENSSL_zalloc(sizeof(EVP_MAC_IMPL));
}
static void siphash_free(EVP_MAC_IMPL *sctx)
{
OPENSSL_free(sctx);
}
static int siphash_copy(EVP_MAC_IMPL *sdst, EVP_MAC_IMPL *ssrc)
{
*sdst = *ssrc;
return 1;
}
static size_t siphash_size(EVP_MAC_IMPL *sctx)
{
return SipHash_hash_size(&sctx->ctx);
}
static int siphash_init(EVP_MAC_IMPL *sctx)
{
/* Not much to do here, actual initialization happens through controls */
return 1;
}
static int siphash_update(EVP_MAC_IMPL *sctx, const unsigned char *data,
size_t datalen)
{
SipHash_Update(&sctx->ctx, data, datalen);
return 1;
}
static int siphash_final(EVP_MAC_IMPL *sctx, unsigned char *out)
{
size_t hlen = siphash_size(sctx);
return SipHash_Final(&sctx->ctx, out, hlen);
}
static int siphash_ctrl(EVP_MAC_IMPL *sctx, int cmd, va_list args)
{
switch (cmd) {
case EVP_MAC_CTRL_SET_SIZE:
{
size_t size = va_arg(args, size_t);
return SipHash_set_hash_size(&sctx->ctx, size);
}
break;
case EVP_MAC_CTRL_SET_KEY:
{
const unsigned char *key = va_arg(args, const unsigned char *);
size_t keylen = va_arg(args, size_t);
if (key == NULL || keylen != SIPHASH_KEY_SIZE)
return 0;
return SipHash_Init(&sctx->ctx, key, 0, 0);
}
break;
default:
return -2;
}
return 1;
}
static int siphash_ctrl_int(EVP_MAC_IMPL *sctx, int cmd, ...)
{
int rv;
va_list args;
va_start(args, cmd);
rv = siphash_ctrl(sctx, cmd, args);
va_end(args);
return rv;
}
static int siphash_ctrl_str_cb(void *ctx, int cmd, void *buf, size_t buflen)
{
return siphash_ctrl_int(ctx, cmd, buf, buflen);
}
static int siphash_ctrl_str(EVP_MAC_IMPL *ctx,
const char *type, const char *value)
{
if (value == NULL)
return 0;
if (strcmp(type, "digestsize") == 0) {
size_t hash_size = atoi(value);
return siphash_ctrl_int(ctx, EVP_MAC_CTRL_SET_SIZE, hash_size);
}
if (strcmp(type, "key") == 0)
return EVP_str2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
value);
if (strcmp(type, "hexkey") == 0)
return EVP_hex2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
value);
return -2;
}
const EVP_MAC siphash_meth = {
EVP_MAC_SIPHASH,
siphash_new,
siphash_copy,
siphash_free,
siphash_size,
siphash_init,
siphash_update,
siphash_final,
siphash_ctrl,
siphash_ctrl_str
};
-205
View File
@@ -1,205 +0,0 @@
/*
* Copyright 2007-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
*/
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include "internal/siphash.h"
#include "siphash_local.h"
#include "internal/evp_int.h"
/* SIPHASH pkey context structure */
typedef struct siphash_pkey_ctx_st {
ASN1_OCTET_STRING ktmp; /* Temp storage for key */
SIPHASH ctx;
} SIPHASH_PKEY_CTX;
static int pkey_siphash_init(EVP_PKEY_CTX *ctx)
{
SIPHASH_PKEY_CTX *pctx;
if ((pctx = OPENSSL_zalloc(sizeof(*pctx))) == NULL) {
CRYPTOerr(CRYPTO_F_PKEY_SIPHASH_INIT, ERR_R_MALLOC_FAILURE);
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_siphash_cleanup(EVP_PKEY_CTX *ctx)
{
SIPHASH_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_siphash_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
{
SIPHASH_PKEY_CTX *sctx, *dctx;
/* allocate memory for dst->data and a new SIPHASH_CTX in dst->data->ctx */
if (!pkey_siphash_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 SIPHASH_PKEY_CTX in dst->data */
pkey_siphash_cleanup(dst);
return 0;
}
memcpy(&dctx->ctx, &sctx->ctx, sizeof(SIPHASH));
return 1;
}
static int pkey_siphash_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
ASN1_OCTET_STRING *key;
SIPHASH_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_SIPHASH(pkey, key);
}
static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
SipHash_Update(&pctx->ctx, data, count);
return 1;
}
static int siphash_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
SIPHASH_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(ctx);
const unsigned char* key;
size_t len;
key = EVP_PKEY_get0_siphash(EVP_PKEY_CTX_get0_pkey(ctx), &len);
if (key == NULL || len != SIPHASH_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);
return SipHash_Init(&pctx->ctx, key, 0, 0);
}
static int siphash_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
EVP_MD_CTX *mctx)
{
SIPHASH_PKEY_CTX *pctx = ctx->data;
*siglen = SipHash_hash_size(&pctx->ctx);
if (sig != NULL)
return SipHash_Final(&pctx->ctx, sig, *siglen);
return 1;
}
static int pkey_siphash_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
SIPHASH_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_DIGEST_SIZE:
return SipHash_set_hash_size(&pctx->ctx, p1);
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_siphash(EVP_PKEY_CTX_get0_pkey(ctx), &len);
}
if (key == NULL || len != SIPHASH_KEY_SIZE ||
!ASN1_OCTET_STRING_set(&pctx->ktmp, key, len))
return 0;
/* use default rounds (2,4) */
return SipHash_Init(&pctx->ctx, ASN1_STRING_get0_data(&pctx->ktmp),
0, 0);
default:
return -2;
}
return 1;
}
static int pkey_siphash_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
if (value == NULL)
return 0;
if (strcmp(type, "digestsize") == 0) {
size_t hash_size = atoi(value);
return pkey_siphash_ctrl(ctx, EVP_PKEY_CTRL_SET_DIGEST_SIZE, hash_size,
NULL);
}
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 siphash_pkey_meth = {
EVP_PKEY_SIPHASH,
EVP_PKEY_FLAG_SIGCTX_CUSTOM, /* we don't deal with a separate MD */
pkey_siphash_init,
pkey_siphash_copy,
pkey_siphash_cleanup,
0, 0,
0,
pkey_siphash_keygen,
0, 0,
0, 0,
0, 0,
siphash_signctx_init,
siphash_signctx,
0, 0,
0, 0,
0, 0,
0, 0,
pkey_siphash_ctrl,
pkey_siphash_ctrl_str
};
+3 -2
View File
@@ -11,6 +11,7 @@
#include "internal/sm2.h"
#include "internal/sm2err.h"
#include "internal/ec_int.h" /* ecdh_KDF_X9_63() */
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/bn.h>
@@ -203,7 +204,7 @@ int sm2_encrypt(const EC_KEY *key,
}
/* X9.63 with no salt happens to match the KDF used in SM2 */
if (!ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
if (!ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
digest)) {
SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB);
goto done;
@@ -344,7 +345,7 @@ int sm2_decrypt(const EC_KEY *key,
if (BN_bn2binpad(x2, x2y2, field_size) < 0
|| BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0
|| !ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
|| !ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
digest)) {
SM2err(SM2_F_SM2_DECRYPT, ERR_R_INTERNAL_ERROR);
goto done;
+5 -6
View File
@@ -517,15 +517,14 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
/* check_purpose() makes the callback as needed */
if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca))
return 0;
/* Check pathlen if not self issued */
if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
&& (x->ex_pathlen != -1)
&& (plen > (x->ex_pathlen + proxy_path_length + 1))) {
/* Check pathlen */
if ((i > 1) && (x->ex_pathlen != -1)
&& (plen > (x->ex_pathlen + proxy_path_length))) {
if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED))
return 0;
}
/* Increment path length if not self issued */
if (!(x->ex_flags & EXFLAG_SI))
/* Increment path length if not a self issued intermediate CA */
if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0)
plen++;
/*
* If this certificate is a proxy certificate, the next certificate
+24 -2
View File
@@ -14,6 +14,7 @@
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
#include <openssl/bn.h>
#include "internal/x509_int.h"
#include "ext_dat.h"
@@ -435,6 +436,27 @@ int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc)
return X509_V_OK;
}
/*
* Return nonzero if the GeneralSubtree has valid 'minimum' field
* (must be absent or 0) and valid 'maximum' field (must be absent).
*/
static int nc_minmax_valid(GENERAL_SUBTREE *sub) {
BIGNUM *bn = NULL;
int ok = 1;
if (sub->maximum)
ok = 0;
if (sub->minimum) {
bn = ASN1_INTEGER_to_BN(sub->minimum, NULL);
if (bn == NULL || !BN_is_zero(bn))
ok = 0;
BN_free(bn);
}
return ok;
}
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
{
GENERAL_SUBTREE *sub;
@@ -449,7 +471,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
if (gen->type != sub->base->type)
continue;
if (sub->minimum || sub->maximum)
if (!nc_minmax_valid(sub))
return X509_V_ERR_SUBTREE_MINMAX;
/* If we already have a match don't bother trying any more */
if (match == 2)
@@ -472,7 +494,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
if (gen->type != sub->base->type)
continue;
if (sub->minimum || sub->maximum)
if (!nc_minmax_valid(sub))
return X509_V_ERR_SUBTREE_MINMAX;
r = nc_match_single(gen, sub->base);