Latest update.
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
# Note that these directories are filtered in Configure. Look for %skipdir
|
||||
# there for further explanations.
|
||||
SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
|
||||
txt_db pkcs7 pkcs12 ui kdf store \
|
||||
md2 md4 md5 sha mdc2 gmac hmac ripemd whrlpool poly1305 blake2 \
|
||||
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
|
||||
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
|
||||
err comp ocsp cms ts srp cmac ct async
|
||||
|
||||
LIBS=../libcrypto
|
||||
SOURCE[../libcrypto]=\
|
||||
cryptlib.c mem.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
|
||||
|
||||
@@ -223,6 +223,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
} while (BN_is_zero(k));
|
||||
|
||||
BN_set_flags(k, BN_FLG_CONSTTIME);
|
||||
BN_set_flags(l, BN_FLG_CONSTTIME);
|
||||
|
||||
if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
|
||||
if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
|
||||
|
||||
@@ -28,6 +28,13 @@
|
||||
# define CHECK_BSD_STYLE_MACROS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ONE global file descriptor for all sessions. This allows operations
|
||||
* such as digest session data copying (see digest_copy()), but is also
|
||||
* saner... why re-open /dev/crypto for every session?
|
||||
*/
|
||||
static int cfd;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Ciphers
|
||||
@@ -39,7 +46,6 @@
|
||||
*****/
|
||||
|
||||
struct cipher_ctx {
|
||||
int cfd;
|
||||
struct session_op sess;
|
||||
|
||||
/* to pass from init to do_cipher */
|
||||
@@ -135,19 +141,13 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const struct cipher_data_st *cipher_d =
|
||||
get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
|
||||
|
||||
if ((cipher_ctx->cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
|
||||
SYSerr(SYS_F_OPEN, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
|
||||
cipher_ctx->sess.cipher = cipher_d->devcryptoid;
|
||||
cipher_ctx->sess.keylen = cipher_d->keylen;
|
||||
cipher_ctx->sess.key = (void *)key;
|
||||
cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
|
||||
if (ioctl(cipher_ctx->cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
|
||||
if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
close(cipher_ctx->cfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
cryp.flags = COP_FLAG_WRITE_IV;
|
||||
#endif
|
||||
|
||||
if (ioctl(cipher_ctx->cfd, CIOCCRYPT, &cryp) < 0) {
|
||||
if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
@@ -212,14 +212,10 @@ static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
struct cipher_ctx *cipher_ctx =
|
||||
(struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||
|
||||
if (ioctl(cipher_ctx->cfd, CIOCFSESSION, &cipher_ctx->sess.ses) < 0) {
|
||||
if (ioctl(cfd, CIOCFSESSION, &cipher_ctx->sess.ses) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
if (close(cipher_ctx->cfd) < 0) {
|
||||
SYSerr(SYS_F_CLOSE, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -233,14 +229,10 @@ static int known_cipher_nids[OSSL_NELEM(cipher_data)];
|
||||
static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
|
||||
static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
|
||||
|
||||
static void prepare_cipher_methods()
|
||||
static void prepare_cipher_methods(void)
|
||||
{
|
||||
size_t i;
|
||||
struct session_op sess;
|
||||
int cfd;
|
||||
|
||||
if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0)
|
||||
return;
|
||||
|
||||
memset(&sess, 0, sizeof(sess));
|
||||
sess.key = (void *)"01234567890123456789012345678901234567890123456789";
|
||||
@@ -281,8 +273,6 @@ static void prepare_cipher_methods()
|
||||
cipher_data[i].nid;
|
||||
}
|
||||
}
|
||||
|
||||
close(cfd);
|
||||
}
|
||||
|
||||
static const EVP_CIPHER *get_cipher_method(int nid)
|
||||
@@ -308,7 +298,7 @@ static void destroy_cipher_method(int nid)
|
||||
known_cipher_methods[i] = NULL;
|
||||
}
|
||||
|
||||
static void destroy_all_cipher_methods()
|
||||
static void destroy_all_cipher_methods(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -329,11 +319,12 @@ static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||
|
||||
/*
|
||||
* We only support digests if the cryptodev implementation supports multiple
|
||||
* data updates. Otherwise, we would be forced to maintain a cache, which is
|
||||
* perilous if there's a lot of data coming in (if someone wants to checksum
|
||||
* an OpenSSL tarball, for example).
|
||||
* data updates and session copying. Otherwise, we would be forced to maintain
|
||||
* a cache, which is perilous if there's a lot of data coming in (if someone
|
||||
* wants to checksum an OpenSSL tarball, for example).
|
||||
*/
|
||||
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||
#if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||
#define IMPLEMENT_DIGEST
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
@@ -346,7 +337,6 @@ static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||
*****/
|
||||
|
||||
struct digest_ctx {
|
||||
int cfd;
|
||||
struct session_op sess;
|
||||
int init;
|
||||
};
|
||||
@@ -413,19 +403,12 @@ static int digest_init(EVP_MD_CTX *ctx)
|
||||
const struct digest_data_st *digest_d =
|
||||
get_digest_data(EVP_MD_CTX_type(ctx));
|
||||
|
||||
if (digest_ctx->init == 0
|
||||
&& (digest_ctx->cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
|
||||
SYSerr(SYS_F_OPEN, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
digest_ctx->init = 1;
|
||||
|
||||
memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess));
|
||||
digest_ctx->sess.mac = digest_d->devcryptoid;
|
||||
if (ioctl(digest_ctx->cfd, CIOCGSESSION, &digest_ctx->sess) < 0) {
|
||||
if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
close(digest_ctx->cfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -444,7 +427,7 @@ static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen,
|
||||
cryp.dst = NULL;
|
||||
cryp.mac = res;
|
||||
cryp.flags = flags;
|
||||
return ioctl(ctx->cfd, CIOCCRYPT, &cryp);
|
||||
return ioctl(cfd, CIOCCRYPT, &cryp);
|
||||
}
|
||||
|
||||
static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
@@ -472,7 +455,7 @@ static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
if (ioctl(digest_ctx->cfd, CIOCFSESSION, &digest_ctx->sess.ses) < 0) {
|
||||
if (ioctl(cfd, CIOCFSESSION, &digest_ctx->sess.ses) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
@@ -480,16 +463,38 @@ static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int digest_cleanup(EVP_MD_CTX *ctx)
|
||||
static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
|
||||
{
|
||||
struct digest_ctx *digest_ctx =
|
||||
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||
struct digest_ctx *digest_from =
|
||||
(struct digest_ctx *)EVP_MD_CTX_md_data(from);
|
||||
struct digest_ctx *digest_to =
|
||||
(struct digest_ctx *)EVP_MD_CTX_md_data(to);
|
||||
struct cphash_op cphash;
|
||||
|
||||
if (close(digest_ctx->cfd) < 0) {
|
||||
SYSerr(SYS_F_CLOSE, errno);
|
||||
if (digest_from == NULL)
|
||||
return 1;
|
||||
|
||||
if (digest_from->init != 1) {
|
||||
SYSerr(SYS_F_IOCTL, EINVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!digest_init(to)) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cphash.src_ses = digest_from->sess.ses;
|
||||
cphash.dst_ses = digest_to->sess.ses;
|
||||
if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int digest_cleanup(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -502,14 +507,10 @@ static int known_digest_nids[OSSL_NELEM(digest_data)];
|
||||
static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
|
||||
static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
|
||||
|
||||
static void prepare_digest_methods()
|
||||
static void prepare_digest_methods(void)
|
||||
{
|
||||
size_t i;
|
||||
struct session_op sess;
|
||||
int cfd;
|
||||
|
||||
if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0)
|
||||
return;
|
||||
|
||||
memset(&sess, 0, sizeof(sess));
|
||||
|
||||
@@ -532,6 +533,7 @@ static void prepare_digest_methods()
|
||||
|| !EVP_MD_meth_set_init(known_digest_methods[i], digest_init)
|
||||
|| !EVP_MD_meth_set_update(known_digest_methods[i], digest_update)
|
||||
|| !EVP_MD_meth_set_final(known_digest_methods[i], digest_final)
|
||||
|| !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy)
|
||||
|| !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
|
||||
|| !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
|
||||
sizeof(struct digest_ctx))) {
|
||||
@@ -541,8 +543,6 @@ static void prepare_digest_methods()
|
||||
known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
|
||||
}
|
||||
}
|
||||
|
||||
close(cfd);
|
||||
}
|
||||
|
||||
static const EVP_MD *get_digest_method(int nid)
|
||||
@@ -568,7 +568,7 @@ static void destroy_digest_method(int nid)
|
||||
known_digest_methods[i] = NULL;
|
||||
}
|
||||
|
||||
static void destroy_all_digest_methods()
|
||||
static void destroy_all_digest_methods(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -598,9 +598,12 @@ static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
|
||||
static int devcrypto_unload(ENGINE *e)
|
||||
{
|
||||
destroy_all_cipher_methods();
|
||||
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||
#ifdef IMPLEMENT_DIGEST
|
||||
destroy_all_digest_methods();
|
||||
#endif
|
||||
|
||||
close(cfd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
@@ -611,23 +614,30 @@ void engine_load_devcrypto_int()
|
||||
{
|
||||
ENGINE *e = NULL;
|
||||
|
||||
if (access("/dev/crypto", R_OK | W_OK) < 0) {
|
||||
fprintf(stderr,
|
||||
"/dev/crypto not present, not enabling devcrypto engine\n");
|
||||
if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
|
||||
fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
prepare_cipher_methods();
|
||||
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||
#ifdef IMPLEMENT_DIGEST
|
||||
prepare_digest_methods();
|
||||
#endif
|
||||
|
||||
if ((e = ENGINE_new()) == NULL)
|
||||
if ((e = ENGINE_new()) == NULL
|
||||
|| !ENGINE_set_destroy_function(e, devcrypto_unload)) {
|
||||
ENGINE_free(e);
|
||||
/*
|
||||
* We know that devcrypto_unload() won't be called when one of the
|
||||
* above two calls have failed, so we close cfd explicitly here to
|
||||
* avoid leaking resources.
|
||||
*/
|
||||
close(cfd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ENGINE_set_id(e, "devcrypto")
|
||||
|| !ENGINE_set_name(e, "/dev/crypto engine")
|
||||
|| !ENGINE_set_destroy_function(e, devcrypto_unload)
|
||||
|
||||
/*
|
||||
* Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
|
||||
@@ -664,7 +674,7 @@ void engine_load_devcrypto_int()
|
||||
# endif
|
||||
#endif
|
||||
|| !ENGINE_set_ciphers(e, devcrypto_ciphers)
|
||||
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||
#ifdef IMPLEMENT_DIGEST
|
||||
|| !ENGINE_set_digests(e, devcrypto_digests)
|
||||
#endif
|
||||
) {
|
||||
|
||||
@@ -801,6 +801,7 @@ EVP_F_EVP_PKEY_VERIFY_RECOVER:144:EVP_PKEY_verify_recover
|
||||
EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT:145:EVP_PKEY_verify_recover_init
|
||||
EVP_F_EVP_SIGNFINAL:107:EVP_SignFinal
|
||||
EVP_F_EVP_VERIFYFINAL:108:EVP_VerifyFinal
|
||||
EVP_F_GMAC_CTRL:215:gmac_ctrl
|
||||
EVP_F_INT_CTX_NEW:157:int_ctx_new
|
||||
EVP_F_OK_NEW:200:ok_new
|
||||
EVP_F_PKCS5_PBE_KEYIVGEN:117:PKCS5_PBE_keyivgen
|
||||
@@ -809,6 +810,7 @@ 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_POLY1305_CTRL:216:poly1305_ctrl
|
||||
EVP_F_RC2_MAGIC_TO_METH:109:rc2_magic_to_meth
|
||||
EVP_F_RC5_CTRL:125:rc5_ctrl
|
||||
EVP_F_S390X_AES_GCM_CTRL:201:s390x_aes_gcm_ctrl
|
||||
@@ -2223,6 +2225,7 @@ EVP_R_ARIA_KEY_SETUP_FAILED:176:aria key setup failed
|
||||
EVP_R_BAD_DECRYPT:100:bad decrypt
|
||||
EVP_R_BUFFER_TOO_SMALL:155:buffer too small
|
||||
EVP_R_CAMELLIA_KEY_SETUP_FAILED:157:camellia key setup failed
|
||||
EVP_R_CIPHER_NOT_GCM_MODE:184:cipher not gcm mode
|
||||
EVP_R_CIPHER_PARAMETER_ERROR:122:cipher parameter error
|
||||
EVP_R_COMMAND_NOT_SUPPORTED:147:command not supported
|
||||
EVP_R_COPY_ERROR:173:copy error
|
||||
|
||||
@@ -15,8 +15,12 @@ void openssl_add_all_macs_int(void)
|
||||
#ifndef OPENSSL_NO_CMAC
|
||||
EVP_add_mac(&cmac_meth);
|
||||
#endif
|
||||
EVP_add_mac(&gmac_meth);
|
||||
EVP_add_mac(&hmac_meth);
|
||||
#ifndef OPENSSL_NO_SIPHASH
|
||||
EVP_add_mac(&siphash_meth);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_POLY1305
|
||||
EVP_add_mac(&poly1305_meth);
|
||||
#endif
|
||||
}
|
||||
@@ -141,6 +141,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
||||
"EVP_PKEY_verify_recover_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_SIGNFINAL, 0), "EVP_SignFinal"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, 0), "EVP_VerifyFinal"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_GMAC_CTRL, 0), "gmac_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_INT_CTX_NEW, 0), "int_ctx_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_OK_NEW, 0), "ok_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_PBE_KEYIVGEN, 0), "PKCS5_PBE_keyivgen"},
|
||||
@@ -152,6 +153,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
||||
"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_POLY1305_CTRL, 0), "poly1305_ctrl"},
|
||||
{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"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"},
|
||||
@@ -170,6 +172,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED),
|
||||
"camellia key setup failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_NOT_GCM_MODE),
|
||||
"cipher not gcm mode"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_PARAMETER_ERROR),
|
||||
"cipher parameter error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COMMAND_NOT_SUPPORTED),
|
||||
|
||||
@@ -425,3 +425,36 @@ const EVP_PKEY_METHOD siphash_pkey_meth = {
|
||||
pkey_mac_ctrl,
|
||||
pkey_mac_ctrl_str
|
||||
};
|
||||
|
||||
const EVP_PKEY_METHOD poly1305_pkey_meth = {
|
||||
EVP_PKEY_POLY1305,
|
||||
EVP_PKEY_FLAG_SIGCTX_CUSTOM,
|
||||
pkey_mac_init,
|
||||
pkey_mac_copy,
|
||||
pkey_mac_cleanup,
|
||||
|
||||
0, 0,
|
||||
|
||||
0,
|
||||
pkey_mac_keygen,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_signctx_init,
|
||||
pkey_mac_signctx,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_mac_ctrl,
|
||||
pkey_mac_ctrl_str
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=gmac.c
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
/* typedef EVP_MAC_IMPL */
|
||||
struct evp_mac_impl_st {
|
||||
EVP_CIPHER *cipher; /* Cache GCM cipher */
|
||||
EVP_CIPHER_CTX *ctx; /* Cipher context */
|
||||
ENGINE *engine; /* Engine implementating the algorithm */
|
||||
};
|
||||
|
||||
static void gmac_free(EVP_MAC_IMPL *gctx)
|
||||
{
|
||||
if (gctx != NULL) {
|
||||
EVP_CIPHER_CTX_free(gctx->ctx);
|
||||
OPENSSL_free(gctx);
|
||||
}
|
||||
}
|
||||
|
||||
static EVP_MAC_IMPL *gmac_new(void)
|
||||
{
|
||||
EVP_MAC_IMPL *gctx;
|
||||
|
||||
if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) == NULL
|
||||
|| (gctx->ctx = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
gmac_free(gctx);
|
||||
return NULL;
|
||||
}
|
||||
return gctx;
|
||||
}
|
||||
|
||||
static int gmac_copy(EVP_MAC_IMPL *gdst, EVP_MAC_IMPL *gsrc)
|
||||
{
|
||||
gdst->cipher = gsrc->cipher;
|
||||
gdst->engine = gsrc->engine;
|
||||
return EVP_CIPHER_CTX_copy(gdst->ctx, gsrc->ctx);
|
||||
}
|
||||
|
||||
static size_t gmac_size(EVP_MAC_IMPL *gctx)
|
||||
{
|
||||
return EVP_GCM_TLS_TAG_LEN;
|
||||
}
|
||||
|
||||
static int gmac_init(EVP_MAC_IMPL *gctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gmac_update(EVP_MAC_IMPL *gctx, const unsigned char *data,
|
||||
size_t datalen)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx = gctx->ctx;
|
||||
int outlen;
|
||||
|
||||
while (datalen > INT_MAX) {
|
||||
if (!EVP_EncryptUpdate(ctx, NULL, &outlen, data, INT_MAX))
|
||||
return 0;
|
||||
data += INT_MAX;
|
||||
datalen -= INT_MAX;
|
||||
}
|
||||
return EVP_EncryptUpdate(ctx, NULL, &outlen, data, datalen);
|
||||
}
|
||||
|
||||
static int gmac_final(EVP_MAC_IMPL *gctx, unsigned char *out)
|
||||
{
|
||||
int hlen;
|
||||
|
||||
if (!EVP_EncryptFinal_ex(gctx->ctx, out, &hlen)
|
||||
|| !EVP_CIPHER_CTX_ctrl(gctx->ctx, EVP_CTRL_AEAD_GET_TAG,
|
||||
gmac_size(gctx), out))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gmac_ctrl(EVP_MAC_IMPL *gctx, int cmd, va_list args)
|
||||
{
|
||||
const unsigned char *p;
|
||||
size_t len;
|
||||
EVP_CIPHER_CTX *ctx = gctx->ctx;
|
||||
const EVP_CIPHER *cipher;
|
||||
ENGINE *engine;
|
||||
|
||||
switch (cmd) {
|
||||
case EVP_MAC_CTRL_SET_CIPHER:
|
||||
cipher = va_arg(args, const EVP_CIPHER *);
|
||||
if (cipher == NULL)
|
||||
return 0;
|
||||
if (EVP_CIPHER_mode(cipher) != EVP_CIPH_GCM_MODE) {
|
||||
EVPerr(EVP_F_GMAC_CTRL, EVP_R_CIPHER_NOT_GCM_MODE);
|
||||
return 0;
|
||||
}
|
||||
return EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL);
|
||||
|
||||
case EVP_MAC_CTRL_SET_KEY:
|
||||
p = va_arg(args, const unsigned char *);
|
||||
len = va_arg(args, size_t);
|
||||
if (len != (size_t)EVP_CIPHER_CTX_key_length(ctx)) {
|
||||
EVPerr(EVP_F_GMAC_CTRL, EVP_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
return EVP_EncryptInit_ex(ctx, NULL, NULL, p, NULL);
|
||||
|
||||
case EVP_MAC_CTRL_SET_IV:
|
||||
p = va_arg(args, const unsigned char *);
|
||||
len = va_arg(args, size_t);
|
||||
return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL)
|
||||
&& EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, p);
|
||||
|
||||
case EVP_MAC_CTRL_SET_ENGINE:
|
||||
engine = va_arg(args, ENGINE *);
|
||||
return EVP_EncryptInit_ex(ctx, NULL, engine, NULL, NULL);
|
||||
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
static int gmac_ctrl_int(EVP_MAC_IMPL *gctx, int cmd, ...)
|
||||
{
|
||||
int rv;
|
||||
va_list args;
|
||||
|
||||
va_start(args, cmd);
|
||||
rv = gmac_ctrl(gctx, cmd, args);
|
||||
va_end(args);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int gmac_ctrl_str_cb(void *gctx, int cmd, void *buf, size_t buflen)
|
||||
{
|
||||
return gmac_ctrl_int(gctx, cmd, buf, buflen);
|
||||
}
|
||||
|
||||
static int gmac_ctrl_str(EVP_MAC_IMPL *gctx, 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 gmac_ctrl_int(gctx, EVP_MAC_CTRL_SET_CIPHER, c);
|
||||
}
|
||||
if (strcmp(type, "key") == 0)
|
||||
return EVP_str2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_KEY,
|
||||
value);
|
||||
if (strcmp(type, "hexkey") == 0)
|
||||
return EVP_hex2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_KEY,
|
||||
value);
|
||||
if (strcmp(type, "iv") == 0)
|
||||
return EVP_str2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_IV,
|
||||
value);
|
||||
if (strcmp(type, "hexiv") == 0)
|
||||
return EVP_hex2ctrl(gmac_ctrl_str_cb, gctx, EVP_MAC_CTRL_SET_IV,
|
||||
value);
|
||||
return -2;
|
||||
}
|
||||
|
||||
const EVP_MAC gmac_meth = {
|
||||
EVP_MAC_GMAC,
|
||||
gmac_new,
|
||||
gmac_copy,
|
||||
gmac_free,
|
||||
gmac_size,
|
||||
gmac_init,
|
||||
gmac_update,
|
||||
gmac_final,
|
||||
gmac_ctrl,
|
||||
gmac_ctrl_str
|
||||
};
|
||||
@@ -129,8 +129,10 @@ struct evp_mac_st {
|
||||
};
|
||||
|
||||
extern const EVP_MAC cmac_meth;
|
||||
extern const EVP_MAC gmac_meth;
|
||||
extern const EVP_MAC hmac_meth;
|
||||
extern const EVP_MAC siphash_meth;
|
||||
extern const EVP_MAC poly1305_meth;
|
||||
|
||||
/*
|
||||
* This function is internal for now, but can be made external when needed.
|
||||
|
||||
@@ -45,9 +45,9 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
|
||||
void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
|
||||
unsigned char *out, size_t outlen);
|
||||
|
||||
size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len);
|
||||
size_t rand_drbg_get_additional_data(RAND_POOL *pool, unsigned char **pout);
|
||||
|
||||
void rand_drbg_cleanup_additional_data(unsigned char *out, size_t outlen);
|
||||
void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out);
|
||||
|
||||
/*
|
||||
* RAND_POOL functions
|
||||
@@ -59,6 +59,7 @@ void rand_pool_free(RAND_POOL *pool);
|
||||
|
||||
const unsigned char *rand_pool_buffer(RAND_POOL *pool);
|
||||
unsigned char *rand_pool_detach(RAND_POOL *pool);
|
||||
void rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer);
|
||||
|
||||
size_t rand_pool_entropy(RAND_POOL *pool);
|
||||
size_t rand_pool_length(RAND_POOL *pool);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
/* Serialized OID's */
|
||||
static const unsigned char so[7762] = {
|
||||
static const unsigned char so[7767] = {
|
||||
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */
|
||||
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */
|
||||
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */
|
||||
@@ -1076,9 +1076,10 @@ static const unsigned char so[7762] = {
|
||||
0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04, /* [ 7736] OBJ_id_tc26_gost_3410_2012_256_paramSetD */
|
||||
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0C, /* [ 7745] OBJ_hmacWithSHA512_224 */
|
||||
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D, /* [ 7753] OBJ_hmacWithSHA512_256 */
|
||||
0x28,0xCC,0x45,0x03,0x04, /* [ 7761] OBJ_gmac */
|
||||
};
|
||||
|
||||
#define NUM_NID 1196
|
||||
#define NUM_NID 1197
|
||||
static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||
{"UNDEF", "undefined", NID_undef},
|
||||
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
|
||||
@@ -2275,10 +2276,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
|
||||
{"magma-mac", "magma-mac", NID_magma_mac},
|
||||
{"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]},
|
||||
{"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]},
|
||||
{"GMAC", "gmac", NID_gmac, 5, &so[7761]},
|
||||
{"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft },
|
||||
};
|
||||
|
||||
#define NUM_SN 1187
|
||||
#define NUM_SN 1188
|
||||
static const unsigned int sn_objs[NUM_SN] = {
|
||||
364, /* "AD_DVCS" */
|
||||
419, /* "AES-128-CBC" */
|
||||
@@ -2396,7 +2398,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
417, /* "CSPName" */
|
||||
1019, /* "ChaCha20" */
|
||||
1018, /* "ChaCha20-Poly1305" */
|
||||
1195, /* "chacha20-poly1305-draft" */
|
||||
1196, /* "chacha20-poly1305-draft" */
|
||||
367, /* "CrlID" */
|
||||
391, /* "DC" */
|
||||
31, /* "DES-CBC" */
|
||||
@@ -2426,6 +2428,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
297, /* "DVCS" */
|
||||
1087, /* "ED25519" */
|
||||
1088, /* "ED448" */
|
||||
1195, /* "GMAC" */
|
||||
99, /* "GN" */
|
||||
1036, /* "HKDF" */
|
||||
855, /* "HMAC" */
|
||||
@@ -3469,7 +3472,7 @@ static const unsigned int sn_objs[NUM_SN] = {
|
||||
1093, /* "x509ExtAdmission" */
|
||||
};
|
||||
|
||||
#define NUM_LN 1187
|
||||
#define NUM_LN 1188
|
||||
static const unsigned int ln_objs[NUM_LN] = {
|
||||
363, /* "AD Time Stamping" */
|
||||
405, /* "ANSI X9.62" */
|
||||
@@ -3848,7 +3851,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
883, /* "certificateRevocationList" */
|
||||
1019, /* "chacha20" */
|
||||
1018, /* "chacha20-poly1305" */
|
||||
1195, /* "ChaCha20-Poly1305-D" */
|
||||
1196, /* "ChaCha20-Poly1305-D" */
|
||||
54, /* "challengePassword" */
|
||||
407, /* "characteristic-two-field" */
|
||||
395, /* "clearance" */
|
||||
@@ -3964,6 +3967,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
509, /* "generationQualifier" */
|
||||
601, /* "generic cryptogram" */
|
||||
99, /* "givenName" */
|
||||
1195, /* "gmac" */
|
||||
976, /* "gost-mac-12" */
|
||||
1009, /* "gost89-cbc" */
|
||||
814, /* "gost89-cnt" */
|
||||
@@ -4660,7 +4664,7 @@ static const unsigned int ln_objs[NUM_LN] = {
|
||||
125, /* "zlib compression" */
|
||||
};
|
||||
|
||||
#define NUM_OBJ 1071
|
||||
#define NUM_OBJ 1072
|
||||
static const unsigned int obj_objs[NUM_OBJ] = {
|
||||
0, /* OBJ_undef 0 */
|
||||
181, /* OBJ_iso 1 */
|
||||
@@ -4907,6 +4911,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
|
||||
637, /* OBJ_set_brand_Diners 2 23 42 8 30 */
|
||||
638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */
|
||||
639, /* OBJ_set_brand_JCB 2 23 42 8 35 */
|
||||
1195, /* OBJ_gmac 1 0 9797 3 4 */
|
||||
1141, /* OBJ_oscca 1 2 156 10197 */
|
||||
805, /* OBJ_cryptopro 1 2 643 2 2 */
|
||||
806, /* OBJ_cryptocom 1 2 643 2 9 */
|
||||
|
||||
@@ -1192,4 +1192,5 @@ magma_cfb 1191
|
||||
magma_mac 1192
|
||||
hmacWithSHA512_224 1193
|
||||
hmacWithSHA512_256 1194
|
||||
chacha20_poly1305_draft 1195
|
||||
gmac 1195
|
||||
chacha20_poly1305_draft 1196
|
||||
@@ -11,6 +11,9 @@ iso 2 : member-body : ISO Member Body
|
||||
|
||||
iso 3 : identified-organization
|
||||
|
||||
# GMAC OID
|
||||
iso 0 9797 3 4 : GMAC : gmac
|
||||
|
||||
# HMAC OIDs
|
||||
identified-organization 6 1 5 5 8 1 1 : HMAC-MD5 : hmac-md5
|
||||
identified-organization 6 1 5 5 8 1 2 : HMAC-SHA1 : hmac-sha1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
poly1305_pmeth.c \
|
||||
poly1305_ameth.c \
|
||||
poly1305_meth.c \
|
||||
poly1305.c {- $target{poly1305_asm_src} -}
|
||||
|
||||
GENERATE[poly1305-sparcv9.S]=asm/poly1305-sparcv9.pl $(PERLASM_SCHEME)
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "internal/poly1305.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include "poly1305_local.h"
|
||||
|
||||
/* typedef EVP_MAC_IMPL */
|
||||
struct evp_mac_impl_st {
|
||||
POLY1305 *ctx; /* poly1305 context */
|
||||
};
|
||||
|
||||
static EVP_MAC_IMPL *poly1305_new(void)
|
||||
{
|
||||
EVP_MAC_IMPL *ctx;
|
||||
|
||||
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL
|
||||
|| (ctx->ctx = OPENSSL_zalloc(sizeof(POLY1305))) == NULL) {
|
||||
OPENSSL_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void poly1305_free(EVP_MAC_IMPL *ctx)
|
||||
{
|
||||
if (ctx != NULL) {
|
||||
OPENSSL_free(ctx->ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static int poly1305_copy(EVP_MAC_IMPL *dst, EVP_MAC_IMPL *src)
|
||||
{
|
||||
*dst->ctx = *src->ctx;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t poly1305_size(EVP_MAC_IMPL *ctx)
|
||||
{
|
||||
return POLY1305_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
static int poly1305_init(EVP_MAC_IMPL *ctx)
|
||||
{
|
||||
/* initialize the context in MAC_ctrl function */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int poly1305_update(EVP_MAC_IMPL *ctx, const unsigned char *data,
|
||||
size_t datalen)
|
||||
{
|
||||
POLY1305 *poly_ctx = ctx->ctx;
|
||||
|
||||
/* poly1305 has nothing to return in its update function */
|
||||
Poly1305_Update(poly_ctx, data, datalen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int poly1305_final(EVP_MAC_IMPL *ctx, unsigned char *out)
|
||||
{
|
||||
POLY1305 *poly_ctx = ctx->ctx;
|
||||
|
||||
Poly1305_Final(poly_ctx, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int poly1305_ctrl(EVP_MAC_IMPL *ctx, int cmd, va_list args)
|
||||
{
|
||||
POLY1305 *poly_ctx = ctx->ctx;
|
||||
unsigned char *key;
|
||||
size_t keylen;
|
||||
|
||||
switch (cmd) {
|
||||
case EVP_MAC_CTRL_SET_KEY:
|
||||
key = va_arg(args, unsigned char *);
|
||||
keylen = va_arg(args, size_t);
|
||||
|
||||
if (keylen != POLY1305_KEY_SIZE) {
|
||||
EVPerr(EVP_F_POLY1305_CTRL, EVP_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
Poly1305_Init(poly_ctx, key);
|
||||
return 1;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int poly1305_ctrl_int(EVP_MAC_IMPL *ctx, int cmd, ...)
|
||||
{
|
||||
int rv;
|
||||
va_list args;
|
||||
|
||||
va_start(args, cmd);
|
||||
rv = poly1305_ctrl(ctx, cmd, args);
|
||||
va_end(args);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int poly1305_ctrl_str_cb(void *ctx, int cmd, void *buf, size_t buflen)
|
||||
{
|
||||
return poly1305_ctrl_int(ctx, cmd, buf, buflen);
|
||||
}
|
||||
|
||||
static int poly1305_ctrl_str(EVP_MAC_IMPL *ctx,
|
||||
const char *type, const char *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return 0;
|
||||
if (strcmp(type, "key") == 0)
|
||||
return EVP_str2ctrl(poly1305_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
|
||||
value);
|
||||
if (strcmp(type, "hexkey") == 0)
|
||||
return EVP_hex2ctrl(poly1305_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
|
||||
value);
|
||||
return -2;
|
||||
}
|
||||
|
||||
const EVP_MAC poly1305_meth = {
|
||||
EVP_MAC_POLY1305,
|
||||
poly1305_new,
|
||||
poly1305_copy,
|
||||
poly1305_free,
|
||||
poly1305_size,
|
||||
poly1305_init,
|
||||
poly1305_update,
|
||||
poly1305_final,
|
||||
poly1305_ctrl,
|
||||
poly1305_ctrl_str
|
||||
};
|
||||
@@ -1,194 +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/poly1305.h"
|
||||
#include "poly1305_local.h"
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
/* POLY1305 pkey context structure */
|
||||
|
||||
typedef struct {
|
||||
ASN1_OCTET_STRING ktmp; /* Temp storage for key */
|
||||
POLY1305 ctx;
|
||||
} POLY1305_PKEY_CTX;
|
||||
|
||||
static int pkey_poly1305_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
POLY1305_PKEY_CTX *pctx;
|
||||
|
||||
if ((pctx = OPENSSL_zalloc(sizeof(*pctx))) == NULL) {
|
||||
CRYPTOerr(CRYPTO_F_PKEY_POLY1305_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_poly1305_cleanup(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
POLY1305_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_poly1305_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
|
||||
{
|
||||
POLY1305_PKEY_CTX *sctx, *dctx;
|
||||
|
||||
/* allocate memory for dst->data and a new POLY1305_CTX in dst->data->ctx */
|
||||
if (!pkey_poly1305_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 POLY1305_PKEY_CTX in dst->data */
|
||||
pkey_poly1305_cleanup(dst);
|
||||
return 0;
|
||||
}
|
||||
memcpy(&dctx->ctx, &sctx->ctx, sizeof(POLY1305));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_poly1305_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
ASN1_OCTET_STRING *key;
|
||||
POLY1305_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_POLY1305(pkey, key);
|
||||
}
|
||||
|
||||
static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
POLY1305_PKEY_CTX *pctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
|
||||
|
||||
Poly1305_Update(&pctx->ctx, data, count);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int poly1305_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||
{
|
||||
POLY1305_PKEY_CTX *pctx = ctx->data;
|
||||
ASN1_OCTET_STRING *key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
|
||||
|
||||
if (key->length != POLY1305_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);
|
||||
Poly1305_Init(&pctx->ctx, key->data);
|
||||
return 1;
|
||||
}
|
||||
static int poly1305_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||
EVP_MD_CTX *mctx)
|
||||
{
|
||||
POLY1305_PKEY_CTX *pctx = ctx->data;
|
||||
|
||||
*siglen = POLY1305_DIGEST_SIZE;
|
||||
if (sig != NULL)
|
||||
Poly1305_Final(&pctx->ctx, sig);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_poly1305_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
POLY1305_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_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_poly1305(EVP_PKEY_CTX_get0_pkey(ctx), &len);
|
||||
}
|
||||
if (key == NULL || len != POLY1305_KEY_SIZE ||
|
||||
!ASN1_OCTET_STRING_set(&pctx->ktmp, key, len))
|
||||
return 0;
|
||||
Poly1305_Init(&pctx->ctx, ASN1_STRING_get0_data(&pctx->ktmp));
|
||||
break;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_poly1305_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
const char *type, const char *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
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 poly1305_pkey_meth = {
|
||||
EVP_PKEY_POLY1305,
|
||||
EVP_PKEY_FLAG_SIGCTX_CUSTOM, /* we don't deal with a separate MD */
|
||||
pkey_poly1305_init,
|
||||
pkey_poly1305_copy,
|
||||
pkey_poly1305_cleanup,
|
||||
|
||||
0, 0,
|
||||
|
||||
0,
|
||||
pkey_poly1305_keygen,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
poly1305_signctx_init,
|
||||
poly1305_signctx,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
|
||||
pkey_poly1305_ctrl,
|
||||
pkey_poly1305_ctrl_str
|
||||
};
|
||||
+27
-11
@@ -158,8 +158,10 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
|
||||
}
|
||||
|
||||
/* If set is called multiple times - clear the old one */
|
||||
if (type != drbg->type && drbg->type != 0 && drbg->meth != NULL) {
|
||||
if (drbg->type != 0 && (type != drbg->type || flags != drbg->flags)) {
|
||||
drbg->meth->uninstantiate(drbg);
|
||||
rand_pool_free(drbg->adin_pool);
|
||||
drbg->adin_pool = NULL;
|
||||
}
|
||||
|
||||
drbg->state = DRBG_UNINITIALISED;
|
||||
@@ -168,6 +170,7 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
|
||||
|
||||
if (type == 0) {
|
||||
/* Uninitialized; that's okay. */
|
||||
drbg->meth = NULL;
|
||||
return 1;
|
||||
} else if (is_ctr(type)) {
|
||||
ret = drbg_ctr_init(drbg);
|
||||
@@ -177,12 +180,17 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
|
||||
else
|
||||
ret = drbg_hash_init(drbg);
|
||||
} else {
|
||||
drbg->type = 0;
|
||||
drbg->flags = 0;
|
||||
drbg->meth = NULL;
|
||||
RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
if (ret == 0) {
|
||||
drbg->state = DRBG_ERROR;
|
||||
RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_ERROR_INITIALISING_DRBG);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -287,10 +295,7 @@ static RAND_DRBG *rand_drbg_new(int secure,
|
||||
return drbg;
|
||||
|
||||
err:
|
||||
if (drbg->secure)
|
||||
OPENSSL_secure_free(drbg);
|
||||
else
|
||||
OPENSSL_free(drbg);
|
||||
RAND_DRBG_free(drbg);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -315,6 +320,7 @@ void RAND_DRBG_free(RAND_DRBG *drbg)
|
||||
|
||||
if (drbg->meth != NULL)
|
||||
drbg->meth->uninstantiate(drbg);
|
||||
rand_pool_free(drbg->adin_pool);
|
||||
CRYPTO_THREAD_lock_free(drbg->lock);
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
|
||||
|
||||
@@ -431,6 +437,7 @@ int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
|
||||
{
|
||||
int index = -1, type, flags;
|
||||
if (drbg->meth == NULL) {
|
||||
drbg->state = DRBG_ERROR;
|
||||
RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE,
|
||||
RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
|
||||
return 0;
|
||||
@@ -722,9 +729,18 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
|
||||
unsigned char *additional = NULL;
|
||||
size_t additional_len;
|
||||
size_t chunk;
|
||||
size_t ret;
|
||||
size_t ret = 0;
|
||||
|
||||
additional_len = rand_drbg_get_additional_data(&additional, drbg->max_adinlen);
|
||||
if (drbg->adin_pool == NULL) {
|
||||
if (drbg->type == 0)
|
||||
goto err;
|
||||
drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen);
|
||||
if (drbg->adin_pool == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
additional_len = rand_drbg_get_additional_data(drbg->adin_pool,
|
||||
&additional);
|
||||
|
||||
for ( ; outlen > 0; outlen -= chunk, out += chunk) {
|
||||
chunk = outlen;
|
||||
@@ -736,9 +752,9 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (additional_len != 0)
|
||||
OPENSSL_secure_clear_free(additional, additional_len);
|
||||
err:
|
||||
if (additional != NULL)
|
||||
rand_drbg_cleanup_additional_data(drbg->adin_pool, additional);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -205,6 +205,11 @@ struct rand_drbg_st {
|
||||
*/
|
||||
struct rand_pool_st *pool;
|
||||
|
||||
/*
|
||||
* Auxiliary pool for additional data.
|
||||
*/
|
||||
struct rand_pool_st *adin_pool;
|
||||
|
||||
/*
|
||||
* The following parameters are setup by the per-type "init" function.
|
||||
*
|
||||
|
||||
+25
-12
@@ -279,14 +279,9 @@ void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
|
||||
* On success it allocates a buffer at |*pout| and returns the length of
|
||||
* the data. The buffer should get freed using OPENSSL_secure_clear_free().
|
||||
*/
|
||||
size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len)
|
||||
size_t rand_drbg_get_additional_data(RAND_POOL *pool, unsigned char **pout)
|
||||
{
|
||||
size_t ret = 0;
|
||||
RAND_POOL *pool;
|
||||
|
||||
pool = rand_pool_new(0, 0, max_len);
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
|
||||
if (rand_pool_add_additional_data(pool) == 0)
|
||||
goto err;
|
||||
@@ -295,14 +290,12 @@ size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len)
|
||||
*pout = rand_pool_detach(pool);
|
||||
|
||||
err:
|
||||
rand_pool_free(pool);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rand_drbg_cleanup_additional_data(unsigned char *out, size_t outlen)
|
||||
void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out)
|
||||
{
|
||||
OPENSSL_secure_clear_free(out, outlen);
|
||||
rand_pool_reattach(pool, out);
|
||||
}
|
||||
|
||||
void rand_fork(void)
|
||||
@@ -536,17 +529,27 @@ size_t rand_pool_length(RAND_POOL *pool)
|
||||
/*
|
||||
* Detach the |pool| buffer and return it to the caller.
|
||||
* It's the responsibility of the caller to free the buffer
|
||||
* using OPENSSL_secure_clear_free().
|
||||
* using OPENSSL_secure_clear_free() or to re-attach it
|
||||
* again to the pool using rand_pool_reattach().
|
||||
*/
|
||||
unsigned char *rand_pool_detach(RAND_POOL *pool)
|
||||
{
|
||||
unsigned char *ret = pool->buffer;
|
||||
pool->buffer = NULL;
|
||||
pool->len = 0;
|
||||
pool->entropy = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-attach the |pool| buffer. It is only allowed to pass
|
||||
* the |buffer| which was previously detached from the same pool.
|
||||
*/
|
||||
void rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer)
|
||||
{
|
||||
pool->buffer = buffer;
|
||||
OPENSSL_cleanse(pool->buffer, pool->len);
|
||||
pool->len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If |entropy_factor| bits contain 1 bit of entropy, how many bytes does one
|
||||
@@ -643,6 +646,11 @@ int rand_pool_add(RAND_POOL *pool,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pool->buffer == NULL) {
|
||||
RANDerr(RAND_F_RAND_POOL_ADD, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
memcpy(pool->buffer + pool->len, buffer, len);
|
||||
pool->len += len;
|
||||
@@ -674,6 +682,11 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pool->buffer == NULL) {
|
||||
RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pool->buffer + pool->len;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user