Latest update.

This commit is contained in:
2018-11-07 08:48:19 +09:00
parent 35dea6db7e
commit 6a5fe3f2fd
58 changed files with 1042 additions and 567 deletions
+9
View File
@@ -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 \
+1
View File
@@ -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,
+68 -58
View File
@@ -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
) {
+3
View File
@@ -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
+4
View File
@@ -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
}
+4
View File
@@ -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),
+33
View File
@@ -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
};
+2
View File
@@ -0,0 +1,2 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=gmac.c
+183
View File
@@ -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
};
+2
View File
@@ -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.
+3 -2
View File
@@ -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);
+12 -7
View File
@@ -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 */
+2 -1
View File
@@ -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
+3
View File
@@ -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 -1
View File
@@ -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)
+141
View File
@@ -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
};
-194
View File
@@ -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
View File
@@ -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;
}
+5
View File
@@ -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
View File
@@ -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;
}