Latest update.
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core_numbers.h>
|
||||
#include "prov/bio.h"
|
||||
|
||||
static OSSL_BIO_new_file_fn *c_bio_new_file = NULL;
|
||||
static OSSL_BIO_new_membuf_fn *c_bio_new_membuf = NULL;
|
||||
static OSSL_BIO_read_ex_fn *c_bio_read_ex = NULL;
|
||||
static OSSL_BIO_free_fn *c_bio_free = NULL;
|
||||
static OSSL_BIO_vprintf_fn *c_bio_vprintf = NULL;
|
||||
|
||||
int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns)
|
||||
{
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
switch (fns->function_id) {
|
||||
case OSSL_FUNC_BIO_NEW_FILE:
|
||||
if (c_bio_new_file == NULL)
|
||||
c_bio_new_file = OSSL_get_BIO_new_file(fns);
|
||||
break;
|
||||
case OSSL_FUNC_BIO_NEW_MEMBUF:
|
||||
if (c_bio_new_membuf == NULL)
|
||||
c_bio_new_membuf = OSSL_get_BIO_new_membuf(fns);
|
||||
break;
|
||||
case OSSL_FUNC_BIO_READ_EX:
|
||||
if (c_bio_read_ex == NULL)
|
||||
c_bio_read_ex = OSSL_get_BIO_read_ex(fns);
|
||||
break;
|
||||
case OSSL_FUNC_BIO_FREE:
|
||||
if (c_bio_free == NULL)
|
||||
c_bio_free = OSSL_get_BIO_free(fns);
|
||||
break;
|
||||
case OSSL_FUNC_BIO_VPRINTF:
|
||||
if (c_bio_vprintf == NULL)
|
||||
c_bio_vprintf = OSSL_get_BIO_vprintf(fns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BIO *ossl_prov_bio_new_file(const char *filename, const char *mode)
|
||||
{
|
||||
if (c_bio_new_file == NULL)
|
||||
return NULL;
|
||||
return c_bio_new_file(filename, mode);
|
||||
}
|
||||
|
||||
BIO *ossl_prov_bio_new_membuf(const char *filename, int len)
|
||||
{
|
||||
if (c_bio_new_membuf == NULL)
|
||||
return NULL;
|
||||
return c_bio_new_membuf(filename, len);
|
||||
}
|
||||
|
||||
int ossl_prov_bio_read_ex(BIO *bio, void *data, size_t data_len,
|
||||
size_t *bytes_read)
|
||||
{
|
||||
if (c_bio_read_ex == NULL)
|
||||
return 0;
|
||||
return c_bio_read_ex(bio, data, data_len, bytes_read);
|
||||
}
|
||||
|
||||
int ossl_prov_bio_free(BIO *bio)
|
||||
{
|
||||
if (c_bio_free == NULL)
|
||||
return 0;
|
||||
return c_bio_free(bio);
|
||||
}
|
||||
|
||||
int ossl_prov_bio_vprintf(BIO *bio, const char *format, va_list ap)
|
||||
{
|
||||
if (c_bio_vprintf == NULL)
|
||||
return -1;
|
||||
return c_bio_vprintf(bio, format, ap);
|
||||
}
|
||||
|
||||
int ossl_prov_bio_printf(BIO *bio, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, format);
|
||||
ret = ossl_prov_bio_vprintf(bio, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
SUBDIRS=digests ciphers
|
||||
|
||||
SOURCE[../libcommon.a]=provider_err.c provlib.c
|
||||
SOURCE[../libcommon.a]=provider_err.c bio_prov.c
|
||||
$FIPSCOMMON=provider_util.c
|
||||
SOURCE[../libnonfips.a]=$FIPSCOMMON
|
||||
SOURCE[../libnonfips.a]=$FIPSCOMMON nid_to_name.c
|
||||
SOURCE[../libfips.a]=$FIPSCOMMON
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "cipher_local.h"
|
||||
#include "prov/providercommonerr.h"
|
||||
|
||||
/*
|
||||
* Fills a single block of buffered data from the input, and returns the amount
|
||||
* of data remaining in the input that is a multiple of the blocksize. The buffer
|
||||
* is only filled if it already has some data in it, isn't full already or we
|
||||
* don't have at least one block in the input.
|
||||
*
|
||||
* buf: a buffer of blocksize bytes
|
||||
* buflen: contains the amount of data already in buf on entry. Updated with the
|
||||
* amount of data in buf at the end. On entry *buflen must always be
|
||||
* less than the blocksize
|
||||
* blocksize: size of a block. Must be greater than 0 and a power of 2
|
||||
* in: pointer to a pointer containing the input data
|
||||
* inlen: amount of input data available
|
||||
*
|
||||
* On return buf is filled with as much data as possible up to a full block,
|
||||
* *buflen is updated containing the amount of data in buf. *in is updated to
|
||||
* the new location where input data should be read from, *inlen is updated with
|
||||
* the remaining amount of data in *in. Returns the largest value <= *inlen
|
||||
* which is a multiple of the blocksize.
|
||||
*/
|
||||
size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
|
||||
const unsigned char **in, size_t *inlen)
|
||||
{
|
||||
size_t blockmask = ~(blocksize - 1);
|
||||
|
||||
assert(*buflen <= blocksize);
|
||||
assert(blocksize > 0 && (blocksize & (blocksize - 1)) == 0);
|
||||
|
||||
if (*buflen != blocksize && (*buflen != 0 || *inlen < blocksize)) {
|
||||
size_t bufremain = blocksize - *buflen;
|
||||
|
||||
if (*inlen < bufremain)
|
||||
bufremain = *inlen;
|
||||
memcpy(buf + *buflen, *in, bufremain);
|
||||
*in += bufremain;
|
||||
*inlen -= bufremain;
|
||||
*buflen += bufremain;
|
||||
}
|
||||
|
||||
return *inlen & blockmask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fills the buffer with trailing data from an encryption/decryption that didn't
|
||||
* fit into a full block.
|
||||
*/
|
||||
int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
|
||||
const unsigned char **in, size_t *inlen)
|
||||
{
|
||||
if (*inlen == 0)
|
||||
return 1;
|
||||
|
||||
if (*buflen + *inlen > blocksize) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buf + *buflen, *in, *inlen);
|
||||
*buflen += *inlen;
|
||||
*inlen = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Pad the final block for encryption */
|
||||
void padblock(unsigned char *buf, size_t *buflen, size_t blocksize)
|
||||
{
|
||||
size_t i;
|
||||
unsigned char pad = (unsigned char)(blocksize - *buflen);
|
||||
|
||||
for (i = *buflen; i < blocksize; i++)
|
||||
buf[i] = pad;
|
||||
}
|
||||
|
||||
int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize)
|
||||
{
|
||||
size_t pad, i;
|
||||
size_t len = *buflen;
|
||||
|
||||
if(len != blocksize) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following assumes that the ciphertext has been authenticated.
|
||||
* Otherwise it provides a padding oracle.
|
||||
*/
|
||||
pad = buf[blocksize - 1];
|
||||
if (pad == 0 || pad > blocksize) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < pad; i++) {
|
||||
if (buf[--len] != pad) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*buflen = len;
|
||||
return 1;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# This source is common building blocks for all ciphers in all our providers.
|
||||
SOURCE[../../libcommon.a]=\
|
||||
cipher_common.c cipher_common_hw.c block.c \
|
||||
cipher_gcm.c cipher_gcm_hw.c \
|
||||
cipher_ccm.c cipher_ccm_hw.c
|
||||
@@ -1,421 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* Dispatch functions for ccm mode */
|
||||
|
||||
#include "prov/ciphercommon.h"
|
||||
#include "prov/cipher_ccm.h"
|
||||
#include "prov/providercommonerr.h"
|
||||
|
||||
static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out,
|
||||
size_t *padlen, const unsigned char *in,
|
||||
size_t len);
|
||||
|
||||
static int ccm_tls_init(PROV_CCM_CTX *ctx, unsigned char *aad, size_t alen)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (alen != EVP_AEAD_TLS1_AAD_LEN)
|
||||
return 0;
|
||||
|
||||
/* Save the aad for later use. */
|
||||
memcpy(ctx->buf, aad, alen);
|
||||
ctx->tls_aad_len = alen;
|
||||
|
||||
len = ctx->buf[alen - 2] << 8 | ctx->buf[alen - 1];
|
||||
if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN)
|
||||
return 0;
|
||||
|
||||
/* Correct length for explicit iv. */
|
||||
len -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
|
||||
|
||||
if (!ctx->enc) {
|
||||
if (len < ctx->m)
|
||||
return 0;
|
||||
/* Correct length for tag. */
|
||||
len -= ctx->m;
|
||||
}
|
||||
ctx->buf[alen - 2] = (unsigned char)(len >> 8);
|
||||
ctx->buf[alen - 1] = (unsigned char)(len & 0xff);
|
||||
|
||||
/* Extra padding: tag appended to record. */
|
||||
return ctx->m;
|
||||
}
|
||||
|
||||
static int ccm_tls_iv_set_fixed(PROV_CCM_CTX *ctx, unsigned char *fixed,
|
||||
size_t flen)
|
||||
{
|
||||
if (flen != EVP_CCM_TLS_FIXED_IV_LEN)
|
||||
return 0;
|
||||
|
||||
/* Copy to first part of the iv. */
|
||||
memcpy(ctx->iv, fixed, flen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t ccm_get_ivlen(PROV_CCM_CTX *ctx)
|
||||
{
|
||||
return 15 - ctx->l;
|
||||
}
|
||||
|
||||
int ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
{
|
||||
PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx;
|
||||
const OSSL_PARAM *p;
|
||||
size_t sz;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG);
|
||||
if (p != NULL) {
|
||||
if (p->data_type != OSSL_PARAM_OCTET_STRING) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if ((p->data_size & 1) || (p->data_size < 4) || p->data_size > 16) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAGLEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p->data != NULL) {
|
||||
if (ctx->enc) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_NEEDED);
|
||||
return 0;
|
||||
}
|
||||
memcpy(ctx->buf, p->data, p->data_size);
|
||||
ctx->tag_set = 1;
|
||||
}
|
||||
ctx->m = p->data_size;
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN);
|
||||
if (p != NULL) {
|
||||
size_t ivlen;
|
||||
|
||||
if (!OSSL_PARAM_get_size_t(p, &sz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
ivlen = 15 - sz;
|
||||
if (ivlen < 2 || ivlen > 8) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
|
||||
return 0;
|
||||
}
|
||||
ctx->l = ivlen;
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD);
|
||||
if (p != NULL) {
|
||||
if (p->data_type != OSSL_PARAM_OCTET_STRING) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
sz = ccm_tls_init(ctx, p->data, p->data_size);
|
||||
if (sz == 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DATA);
|
||||
return 0;
|
||||
}
|
||||
ctx->tls_aad_pad_sz = sz;
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED);
|
||||
if (p != NULL) {
|
||||
if (p->data_type != OSSL_PARAM_OCTET_STRING) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (ccm_tls_iv_set_fixed(ctx, p->data, p->data_size) == 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ccm_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
||||
{
|
||||
PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx;
|
||||
OSSL_PARAM *p;
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, ccm_get_ivlen(ctx))) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN);
|
||||
if (p != NULL) {
|
||||
size_t m = ctx->m;
|
||||
|
||||
if (!OSSL_PARAM_set_size_t(p, m)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
|
||||
if (p != NULL) {
|
||||
if (ccm_get_ivlen(ctx) != p->data_size) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
|
||||
return 0;
|
||||
}
|
||||
if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG);
|
||||
if (p != NULL) {
|
||||
if (!ctx->enc || !ctx->tag_set) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOTSET);
|
||||
return 0;
|
||||
}
|
||||
if (p->data_type != OSSL_PARAM_OCTET_STRING) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (!ctx->hw->gettag(ctx, p->data, p->data_size))
|
||||
return 0;
|
||||
ctx->tag_set = 0;
|
||||
ctx->iv_set = 0;
|
||||
ctx->len_set = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ccm_init(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen, int enc)
|
||||
{
|
||||
PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx;
|
||||
|
||||
ctx->enc = enc;
|
||||
|
||||
if (iv != NULL) {
|
||||
if (ivlen != ccm_get_ivlen(ctx)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
|
||||
return 0;
|
||||
}
|
||||
memcpy(ctx->iv, iv, ivlen);
|
||||
ctx->iv_set = 1;
|
||||
}
|
||||
if (key != NULL) {
|
||||
if (keylen != ctx->keylen) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN);
|
||||
return 0;
|
||||
}
|
||||
return ctx->hw->setkey(ctx, key, keylen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ccm_einit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return ccm_init(vctx, key, keylen, iv, ivlen, 1);
|
||||
}
|
||||
|
||||
int ccm_dinit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return ccm_init(vctx, key, keylen, iv, ivlen, 0);
|
||||
}
|
||||
|
||||
int ccm_stream_update(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize, const unsigned char *in,
|
||||
size_t inl)
|
||||
{
|
||||
PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx;
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ccm_cipher_internal(ctx, out, outl, in, inl)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ccm_stream_final(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize)
|
||||
{
|
||||
PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx;
|
||||
int i;
|
||||
|
||||
i = ccm_cipher_internal(ctx, out, outl, NULL, 0);
|
||||
if (i <= 0)
|
||||
return 0;
|
||||
|
||||
*outl = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ccm_cipher(void *vctx,
|
||||
unsigned char *out, size_t *outl, size_t outsize,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx;
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ccm_cipher_internal(ctx, out, outl, in, inl) <= 0)
|
||||
return 0;
|
||||
|
||||
*outl = inl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Copy the buffered iv */
|
||||
static int ccm_set_iv(PROV_CCM_CTX *ctx, size_t mlen)
|
||||
{
|
||||
const PROV_CCM_HW *hw = ctx->hw;
|
||||
|
||||
if (!hw->setiv(ctx, ctx->iv, ccm_get_ivlen(ctx), mlen))
|
||||
return 0;
|
||||
ctx->len_set = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ccm_tls_cipher(PROV_CCM_CTX *ctx,
|
||||
unsigned char *out, size_t *padlen,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
int rv = 0;
|
||||
size_t olen = 0;
|
||||
|
||||
/* Encrypt/decrypt must be performed in place */
|
||||
if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)ctx->m))
|
||||
goto err;
|
||||
|
||||
/* If encrypting set explicit IV from sequence number (start of AAD) */
|
||||
if (ctx->enc)
|
||||
memcpy(out, ctx->buf, EVP_CCM_TLS_EXPLICIT_IV_LEN);
|
||||
/* Get rest of IV from explicit IV */
|
||||
memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN);
|
||||
/* Correct length value */
|
||||
len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m;
|
||||
if (!ccm_set_iv(ctx, len))
|
||||
goto err;
|
||||
|
||||
/* Use saved AAD */
|
||||
if (!ctx->hw->setaad(ctx, ctx->buf, ctx->tls_aad_len))
|
||||
goto err;
|
||||
|
||||
/* Fix buffer to point to payload */
|
||||
in += EVP_CCM_TLS_EXPLICIT_IV_LEN;
|
||||
out += EVP_CCM_TLS_EXPLICIT_IV_LEN;
|
||||
if (ctx->enc) {
|
||||
if (!ctx->hw->auth_encrypt(ctx, in, out, len, out + len, ctx->m))
|
||||
goto err;
|
||||
olen = len + EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m;
|
||||
} else {
|
||||
if (!ctx->hw->auth_decrypt(ctx, in, out, len,
|
||||
(unsigned char *)in + len, ctx->m))
|
||||
goto err;
|
||||
olen = len;
|
||||
}
|
||||
rv = 1;
|
||||
err:
|
||||
*padlen = olen;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out,
|
||||
size_t *padlen, const unsigned char *in,
|
||||
size_t len)
|
||||
{
|
||||
int rv = 0;
|
||||
size_t olen = 0;
|
||||
const PROV_CCM_HW *hw = ctx->hw;
|
||||
|
||||
/* If no key set, return error */
|
||||
if (!ctx->key_set)
|
||||
return 0;
|
||||
|
||||
if (ctx->tls_aad_len != UNINITIALISED_SIZET)
|
||||
return ccm_tls_cipher(ctx, out, padlen, in, len);
|
||||
|
||||
/* EVP_*Final() doesn't return any data */
|
||||
if (in == NULL && out != NULL)
|
||||
goto finish;
|
||||
|
||||
if (!ctx->iv_set)
|
||||
goto err;
|
||||
|
||||
if (out == NULL) {
|
||||
if (in == NULL) {
|
||||
if (!ccm_set_iv(ctx, len))
|
||||
goto err;
|
||||
} else {
|
||||
/* If we have AAD, we need a message length */
|
||||
if (!ctx->len_set && len)
|
||||
goto err;
|
||||
if (!hw->setaad(ctx, in, len))
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
/* If not set length yet do it */
|
||||
if (!ctx->len_set && !ccm_set_iv(ctx, len))
|
||||
goto err;
|
||||
|
||||
if (ctx->enc) {
|
||||
if (!hw->auth_encrypt(ctx, in, out, len, NULL, 0))
|
||||
goto err;
|
||||
ctx->tag_set = 1;
|
||||
} else {
|
||||
/* The tag must be set before actually decrypting data */
|
||||
if (!ctx->tag_set)
|
||||
goto err;
|
||||
|
||||
if (!hw->auth_decrypt(ctx, in, out, len, ctx->buf, ctx->m))
|
||||
goto err;
|
||||
/* Finished - reset flags so calling this method again will fail */
|
||||
ctx->iv_set = 0;
|
||||
ctx->tag_set = 0;
|
||||
ctx->len_set = 0;
|
||||
}
|
||||
}
|
||||
olen = len;
|
||||
finish:
|
||||
rv = 1;
|
||||
err:
|
||||
*padlen = olen;
|
||||
return rv;
|
||||
}
|
||||
|
||||
void ccm_initctx(PROV_CCM_CTX *ctx, size_t keybits, const PROV_CCM_HW *hw)
|
||||
{
|
||||
ctx->keylen = keybits / 8;
|
||||
ctx->key_set = 0;
|
||||
ctx->iv_set = 0;
|
||||
ctx->tag_set = 0;
|
||||
ctx->len_set = 0;
|
||||
ctx->l = 8;
|
||||
ctx->m = 12;
|
||||
ctx->tls_aad_len = UNINITIALISED_SIZET;
|
||||
ctx->hw = hw;
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "prov/ciphercommon.h"
|
||||
#include "prov/cipher_ccm.h"
|
||||
|
||||
int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
|
||||
size_t nlen, size_t mlen)
|
||||
{
|
||||
return CRYPTO_ccm128_setiv(&ctx->ccm_ctx, nonce, nlen, mlen) == 0;
|
||||
}
|
||||
|
||||
int ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad, size_t alen)
|
||||
{
|
||||
CRYPTO_ccm128_aad(&ctx->ccm_ctx, aad, alen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag, size_t tlen)
|
||||
{
|
||||
return CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, tlen) > 0;
|
||||
}
|
||||
|
||||
int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
unsigned char *tag, size_t taglen)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (ctx->str != NULL)
|
||||
rv = CRYPTO_ccm128_encrypt_ccm64(&ctx->ccm_ctx, in,
|
||||
out, len, ctx->str) == 0;
|
||||
else
|
||||
rv = CRYPTO_ccm128_encrypt(&ctx->ccm_ctx, in, out, len) == 0;
|
||||
|
||||
if (rv == 1 && tag != NULL)
|
||||
rv = (CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, taglen) > 0);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
unsigned char *expected_tag, size_t taglen)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (ctx->str != NULL)
|
||||
rv = CRYPTO_ccm128_decrypt_ccm64(&ctx->ccm_ctx, in, out, len,
|
||||
ctx->str) == 0;
|
||||
else
|
||||
rv = CRYPTO_ccm128_decrypt(&ctx->ccm_ctx, in, out, len) == 0;
|
||||
if (rv) {
|
||||
unsigned char tag[16];
|
||||
|
||||
if (!CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, taglen)
|
||||
|| CRYPTO_memcmp(tag, expected_tag, taglen) != 0)
|
||||
rv = 0;
|
||||
}
|
||||
if (rv == 0)
|
||||
OPENSSL_cleanse(out, len);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -1,407 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generic dispatch table functions for ciphers.
|
||||
*/
|
||||
|
||||
#include "cipher_local.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
#include "prov/providercommonerr.h"
|
||||
|
||||
/*-
|
||||
* Generic cipher functions for OSSL_PARAM gettables and settables
|
||||
*/
|
||||
static const OSSL_PARAM cipher_known_gettable_params[] = {
|
||||
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_MODE, NULL),
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, NULL),
|
||||
OSSL_PARAM_ulong(OSSL_CIPHER_PARAM_FLAGS, NULL),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
const OSSL_PARAM *cipher_generic_gettable_params(void)
|
||||
{
|
||||
return cipher_known_gettable_params;
|
||||
}
|
||||
|
||||
int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
|
||||
unsigned long flags,
|
||||
size_t kbits, size_t blkbits, size_t ivbits)
|
||||
{
|
||||
OSSL_PARAM *p;
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE);
|
||||
if (p != NULL && !OSSL_PARAM_set_uint(p, md)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_FLAGS);
|
||||
if (p != NULL && !OSSL_PARAM_set_ulong(p, flags)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits / 8)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits / 8)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits / 8)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic)
|
||||
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic)
|
||||
|
||||
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_generic)
|
||||
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_generic)
|
||||
|
||||
/*-
|
||||
* AEAD cipher functions for OSSL_PARAM gettables and settables
|
||||
*/
|
||||
static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = {
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL),
|
||||
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
const OSSL_PARAM *cipher_aead_gettable_ctx_params(void)
|
||||
{
|
||||
return cipher_aead_known_gettable_ctx_params;
|
||||
}
|
||||
|
||||
static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = {
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_IVLEN, NULL),
|
||||
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
const OSSL_PARAM *cipher_aead_settable_ctx_params(void)
|
||||
{
|
||||
return cipher_aead_known_settable_ctx_params;
|
||||
}
|
||||
|
||||
static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
|
||||
const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen,
|
||||
int enc)
|
||||
{
|
||||
ctx->enc = enc ? 1 : 0;
|
||||
|
||||
if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
|
||||
if (!cipher_generic_initiv(ctx, iv, ivlen))
|
||||
return 0;
|
||||
}
|
||||
if (key != NULL) {
|
||||
if ((ctx->flags & EVP_CIPH_VARIABLE_LENGTH) == 0) {
|
||||
if (keylen != ctx->keylen) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ctx->keylen = keylen;
|
||||
}
|
||||
return ctx->hw->init(ctx, key, ctx->keylen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_generic_einit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
|
||||
iv, ivlen, 1);
|
||||
}
|
||||
|
||||
int cipher_generic_dinit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen,
|
||||
iv, ivlen, 0);
|
||||
}
|
||||
|
||||
int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize, const unsigned char *in,
|
||||
size_t inl)
|
||||
{
|
||||
size_t outlint = 0;
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
size_t blksz = ctx->blocksize;
|
||||
size_t nextblocks = fillblock(ctx->buf, &ctx->bufsz, blksz, &in, &inl);
|
||||
|
||||
/*
|
||||
* If we're decrypting and we end an update on a block boundary we hold
|
||||
* the last block back in case this is the last update call and the last
|
||||
* block is padded.
|
||||
*/
|
||||
if (ctx->bufsz == blksz && (ctx->enc || inl > 0 || !ctx->pad)) {
|
||||
if (outsize < blksz) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
ctx->bufsz = 0;
|
||||
outlint = blksz;
|
||||
out += blksz;
|
||||
}
|
||||
if (nextblocks > 0) {
|
||||
if (!ctx->enc && ctx->pad && nextblocks == inl) {
|
||||
if (!ossl_assert(inl >= blksz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
nextblocks -= blksz;
|
||||
}
|
||||
outlint += nextblocks;
|
||||
if (outsize < outlint) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
if (!ctx->hw->cipher(ctx, out, in, nextblocks)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
in += nextblocks;
|
||||
inl -= nextblocks;
|
||||
}
|
||||
if (!trailingdata(ctx->buf, &ctx->bufsz, blksz, &in, &inl)) {
|
||||
/* ERR_raise already called */
|
||||
return 0;
|
||||
}
|
||||
|
||||
*outl = outlint;
|
||||
return inl == 0;
|
||||
}
|
||||
|
||||
int cipher_generic_block_final(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize)
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
size_t blksz = ctx->blocksize;
|
||||
|
||||
if (ctx->enc) {
|
||||
if (ctx->pad) {
|
||||
padblock(ctx->buf, &ctx->bufsz, blksz);
|
||||
} else if (ctx->bufsz == 0) {
|
||||
*outl = 0;
|
||||
return 1;
|
||||
} else if (ctx->bufsz != blksz) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (outsize < blksz) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
if (!ctx->hw->cipher(ctx, out, ctx->buf, blksz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
ctx->bufsz = 0;
|
||||
*outl = blksz;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Decrypting */
|
||||
if (ctx->bufsz != blksz) {
|
||||
if (ctx->bufsz == 0 && !ctx->pad) {
|
||||
*outl = 0;
|
||||
return 1;
|
||||
}
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ctx->hw->cipher(ctx, ctx->buf, ctx->buf, blksz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->pad && !unpadblock(ctx->buf, &ctx->bufsz, blksz)) {
|
||||
/* ERR_raise already called */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (outsize < ctx->bufsz) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
memcpy(out, ctx->buf, ctx->bufsz);
|
||||
*outl = ctx->bufsz;
|
||||
ctx->bufsz = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_generic_stream_update(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize, const unsigned char *in,
|
||||
size_t inl)
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ctx->hw->cipher(ctx, out, in, inl)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*outl = inl;
|
||||
return 1;
|
||||
}
|
||||
int cipher_generic_stream_final(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize)
|
||||
{
|
||||
*outl = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_generic_cipher(void *vctx,
|
||||
unsigned char *out, size_t *outl, size_t outsize,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ctx->hw->cipher(ctx, out, in, inl)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*outl = inl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
OSSL_PARAM *p;
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING);
|
||||
if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->pad)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
|
||||
if (p != NULL
|
||||
&& !OSSL_PARAM_set_octet_ptr(p, &ctx->oiv, ctx->ivlen)
|
||||
&& !OSSL_PARAM_set_octet_string(p, &ctx->oiv, ctx->ivlen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM);
|
||||
if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->num)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING);
|
||||
if (p != NULL) {
|
||||
unsigned int pad;
|
||||
|
||||
if (!OSSL_PARAM_get_uint(p, &pad)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
ctx->pad = pad ? 1 : 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_NUM);
|
||||
if (p != NULL) {
|
||||
unsigned int num;
|
||||
|
||||
if (!OSSL_PARAM_get_uint(p, &num)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
ctx->num = num;
|
||||
}
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
|
||||
if (p != NULL) {
|
||||
size_t keylen;
|
||||
|
||||
if (!OSSL_PARAM_get_size_t(p, &keylen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
ctx->keylen = keylen;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
|
||||
size_t ivlen)
|
||||
{
|
||||
if (ivlen != ctx->ivlen
|
||||
|| ivlen > sizeof(ctx->iv)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
|
||||
return 0;
|
||||
}
|
||||
ctx->iv_set = 1;
|
||||
memcpy(ctx->iv, iv, ivlen);
|
||||
memcpy(ctx->oiv, iv, ivlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
|
||||
size_t ivbits, unsigned int mode, uint64_t flags,
|
||||
const PROV_CIPHER_HW *hw, void *provctx)
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
|
||||
ctx->flags = flags;
|
||||
ctx->pad = 1;
|
||||
ctx->keylen = ((kbits) / 8);
|
||||
ctx->ivlen = ((ivbits) / 8);
|
||||
ctx->hw = hw;
|
||||
ctx->mode = mode;
|
||||
ctx->blocksize = blkbits / 8;
|
||||
if (provctx != NULL)
|
||||
ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); /* used for rand */
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "prov/ciphercommon.h"
|
||||
|
||||
/*-
|
||||
* The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
|
||||
* Used if there is no special hardware implementations.
|
||||
*/
|
||||
int cipher_hw_generic_cbc(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
if (dat->stream.cbc)
|
||||
(*dat->stream.cbc) (in, out, len, dat->ks, dat->iv, dat->enc);
|
||||
else if (dat->enc)
|
||||
CRYPTO_cbc128_encrypt(in, out, len, dat->ks, dat->iv, dat->block);
|
||||
else
|
||||
CRYPTO_cbc128_decrypt(in, out, len, dat->ks, dat->iv, dat->block);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_generic_ecb(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
size_t i, bl = dat->blocksize;
|
||||
|
||||
if (len < bl)
|
||||
return 1;
|
||||
|
||||
for (i = 0, len -= bl; i <= len; i += bl)
|
||||
(*dat->block) (in + i, out + i, dat->ks);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_generic_ofb128(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
int num = dat->num;
|
||||
|
||||
CRYPTO_ofb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->block);
|
||||
dat->num = num;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_generic_cfb128(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
int num = dat->num;
|
||||
|
||||
CRYPTO_cfb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc,
|
||||
dat->block);
|
||||
dat->num = num;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_generic_cfb8(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
int num = dat->num;
|
||||
|
||||
CRYPTO_cfb128_8_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc,
|
||||
dat->block);
|
||||
dat->num = num;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_generic_cfb1(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
int num = dat->num;
|
||||
|
||||
if ((dat->flags & EVP_CIPH_FLAG_LENGTH_BITS) != 0) {
|
||||
CRYPTO_cfb128_1_encrypt(in, out, len, dat->ks, dat->iv, &num,
|
||||
dat->enc, dat->block);
|
||||
dat->num = num;
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (len >= MAXBITCHUNK) {
|
||||
CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, dat->ks,
|
||||
dat->iv, &num, dat->enc, dat->block);
|
||||
len -= MAXBITCHUNK;
|
||||
out += MAXBITCHUNK;
|
||||
in += MAXBITCHUNK;
|
||||
}
|
||||
if (len)
|
||||
CRYPTO_cfb128_1_encrypt(in, out, len * 8, dat->ks, dat->iv, &num,
|
||||
dat->enc, dat->block);
|
||||
|
||||
dat->num = num;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_generic_ctr(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
unsigned int num = dat->num;
|
||||
|
||||
if (dat->stream.ctr)
|
||||
CRYPTO_ctr128_encrypt_ctr32(in, out, len, dat->ks, dat->iv, dat->buf,
|
||||
&num, dat->stream.ctr);
|
||||
else
|
||||
CRYPTO_ctr128_encrypt(in, out, len, dat->ks, dat->iv, dat->buf,
|
||||
&num, dat->block);
|
||||
dat->num = num;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* The chunked cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
|
||||
* Used if there is no special hardware implementations.
|
||||
*/
|
||||
|
||||
int cipher_hw_chunked_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
while (inl >= MAXCHUNK) {
|
||||
cipher_hw_generic_cbc(ctx, out, in, MAXCHUNK);
|
||||
inl -= MAXCHUNK;
|
||||
in += MAXCHUNK;
|
||||
out += MAXCHUNK;
|
||||
}
|
||||
if (inl > 0)
|
||||
cipher_hw_generic_cbc(ctx, out, in, inl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_chunked_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
size_t chunk = MAXCHUNK;
|
||||
|
||||
if (inl < chunk)
|
||||
chunk = inl;
|
||||
while (inl > 0 && inl >= chunk) {
|
||||
cipher_hw_generic_cfb8(ctx, out, in, inl);
|
||||
inl -= chunk;
|
||||
in += chunk;
|
||||
out += chunk;
|
||||
if (inl < chunk)
|
||||
chunk = inl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_chunked_cfb128(PROV_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
size_t chunk = MAXCHUNK;
|
||||
|
||||
if (inl < chunk)
|
||||
chunk = inl;
|
||||
while (inl > 0 && inl >= chunk) {
|
||||
cipher_hw_generic_cfb128(ctx, out, in, inl);
|
||||
inl -= chunk;
|
||||
in += chunk;
|
||||
out += chunk;
|
||||
if (inl < chunk)
|
||||
chunk = inl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_chunked_ofb128(PROV_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
while (inl >= MAXCHUNK) {
|
||||
cipher_hw_generic_ofb128(ctx, out, in, MAXCHUNK);
|
||||
inl -= MAXCHUNK;
|
||||
in += MAXCHUNK;
|
||||
out += MAXCHUNK;
|
||||
}
|
||||
if (inl > 0)
|
||||
cipher_hw_generic_ofb128(ctx, out, in, inl);
|
||||
return 1;
|
||||
}
|
||||
@@ -1,509 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* Dispatch functions for gcm mode */
|
||||
|
||||
#include "prov/ciphercommon.h"
|
||||
#include "prov/cipher_gcm.h"
|
||||
#include "prov/providercommonerr.h"
|
||||
#include "crypto/rand.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
|
||||
static int gcm_tls_init(PROV_GCM_CTX *dat, unsigned char *aad, size_t aad_len);
|
||||
static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv,
|
||||
size_t len);
|
||||
static int gcm_tls_cipher(PROV_GCM_CTX *ctx, unsigned char *out, size_t *padlen,
|
||||
const unsigned char *in, size_t len);
|
||||
static int gcm_cipher_internal(PROV_GCM_CTX *ctx, unsigned char *out,
|
||||
size_t *padlen, const unsigned char *in,
|
||||
size_t len);
|
||||
|
||||
void gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits,
|
||||
const PROV_GCM_HW *hw, size_t ivlen_min)
|
||||
{
|
||||
ctx->pad = 1;
|
||||
ctx->mode = EVP_CIPH_GCM_MODE;
|
||||
ctx->taglen = UNINITIALISED_SIZET;
|
||||
ctx->tls_aad_len = UNINITIALISED_SIZET;
|
||||
ctx->ivlen_min = ivlen_min;
|
||||
ctx->ivlen = (EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN);
|
||||
ctx->keylen = keybits / 8;
|
||||
ctx->hw = hw;
|
||||
ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
|
||||
}
|
||||
|
||||
static int gcm_init(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen, int enc)
|
||||
{
|
||||
PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
|
||||
|
||||
ctx->enc = enc;
|
||||
|
||||
if (iv != NULL) {
|
||||
if (ivlen < ctx->ivlen_min || ivlen > sizeof(ctx->iv)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
ctx->ivlen = ivlen;
|
||||
memcpy(ctx->iv, iv, ivlen);
|
||||
ctx->iv_state = IV_STATE_BUFFERED;
|
||||
}
|
||||
|
||||
if (key != NULL) {
|
||||
if (keylen != ctx->keylen) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
return ctx->hw->setkey(ctx, key, ctx->keylen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gcm_einit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return gcm_init(vctx, key, keylen, iv, ivlen, 1);
|
||||
}
|
||||
|
||||
int gcm_dinit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return gcm_init(vctx, key, keylen, iv, ivlen, 0);
|
||||
}
|
||||
|
||||
int gcm_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
||||
{
|
||||
PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
|
||||
OSSL_PARAM *p;
|
||||
size_t sz;
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->ivlen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN);
|
||||
if (p != NULL) {
|
||||
size_t taglen = (ctx->taglen != UNINITIALISED_SIZET) ? ctx->taglen :
|
||||
GCM_TAG_MAX_SIZE;
|
||||
|
||||
if (!OSSL_PARAM_set_size_t(p, taglen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
|
||||
if (p != NULL) {
|
||||
if (ctx->iv_gen != 1 && ctx->iv_gen_rand != 1)
|
||||
return 0;
|
||||
if (ctx->ivlen != p->data_size) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->ivlen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG);
|
||||
if (p != NULL) {
|
||||
sz = p->data_size;
|
||||
if (sz == 0
|
||||
|| sz > EVP_GCM_TLS_TAG_LEN
|
||||
|| !ctx->enc
|
||||
|| ctx->taglen == UNINITIALISED_SIZET) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG);
|
||||
return 0;
|
||||
}
|
||||
if (!OSSL_PARAM_set_octet_string(p, ctx->buf, sz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gcm_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
{
|
||||
PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
|
||||
const OSSL_PARAM *p;
|
||||
size_t sz;
|
||||
void *vp;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG);
|
||||
if (p != NULL) {
|
||||
vp = ctx->buf;
|
||||
if (!OSSL_PARAM_get_octet_string(p, &vp, EVP_GCM_TLS_TAG_LEN, &sz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (sz == 0 || ctx->enc) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG);
|
||||
return 0;
|
||||
}
|
||||
ctx->taglen = sz;
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN);
|
||||
if (p != NULL) {
|
||||
if (!OSSL_PARAM_get_size_t(p, &sz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (sz == 0 || sz > sizeof(ctx->iv)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
ctx->ivlen = sz;
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD);
|
||||
if (p != NULL) {
|
||||
if (p->data_type != OSSL_PARAM_OCTET_STRING) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
sz = gcm_tls_init(ctx, p->data, p->data_size);
|
||||
if (sz == 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_AAD);
|
||||
return 0;
|
||||
}
|
||||
ctx->tls_aad_pad_sz = sz;
|
||||
}
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED);
|
||||
if (p != NULL) {
|
||||
if (p->data_type != OSSL_PARAM_OCTET_STRING) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (gcm_tls_iv_set_fixed(ctx, p->data, p->data_size) == 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(3.0) Temporary solution to address fuzz test crash, which will be
|
||||
* reworked once the discussion in PR #9510 is resolved. i.e- We need a
|
||||
* general solution for handling missing parameters inside set_params and
|
||||
* get_params methods.
|
||||
*/
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
|
||||
if (p != NULL) {
|
||||
size_t keylen;
|
||||
|
||||
if (!OSSL_PARAM_get_size_t(p, &keylen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
/* The key length can not be modified for gcm mode */
|
||||
if (keylen != ctx->keylen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gcm_stream_update(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize, const unsigned char *in, size_t inl)
|
||||
{
|
||||
PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gcm_cipher_internal(ctx, out, outl, in, inl) <= 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gcm_stream_final(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize)
|
||||
{
|
||||
PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
|
||||
int i;
|
||||
|
||||
i = gcm_cipher_internal(ctx, out, outl, NULL, 0);
|
||||
if (i <= 0)
|
||||
return 0;
|
||||
|
||||
*outl = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gcm_cipher(void *vctx,
|
||||
unsigned char *out, size_t *outl, size_t outsize,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx;
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gcm_cipher_internal(ctx, out, outl, in, inl) <= 0)
|
||||
return 0;
|
||||
|
||||
*outl = inl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* See SP800-38D (GCM) Section 8 "Uniqueness requirement on IVS and keys"
|
||||
*
|
||||
* See also 8.2.2 RBG-based construction.
|
||||
* Random construction consists of a free field (which can be NULL) and a
|
||||
* random field which will use a DRBG that can return at least 96 bits of
|
||||
* entropy strength. (The DRBG must be seeded by the FIPS module).
|
||||
*/
|
||||
static int gcm_iv_generate(PROV_GCM_CTX *ctx, int offset)
|
||||
{
|
||||
int sz = ctx->ivlen - offset;
|
||||
|
||||
/* Must be at least 96 bits */
|
||||
if (sz <= 0 || ctx->ivlen < GCM_IV_DEFAULT_SIZE)
|
||||
return 0;
|
||||
|
||||
/* Use DRBG to generate random iv */
|
||||
if (rand_bytes_ex(ctx->libctx, ctx->iv + offset, sz) <= 0)
|
||||
return 0;
|
||||
ctx->iv_state = IV_STATE_BUFFERED;
|
||||
ctx->iv_gen_rand = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gcm_cipher_internal(PROV_GCM_CTX *ctx, unsigned char *out,
|
||||
size_t *padlen, const unsigned char *in,
|
||||
size_t len)
|
||||
{
|
||||
size_t olen = 0;
|
||||
int rv = 0;
|
||||
const PROV_GCM_HW *hw = ctx->hw;
|
||||
|
||||
if (ctx->tls_aad_len != UNINITIALISED_SIZET)
|
||||
return gcm_tls_cipher(ctx, out, padlen, in, len);
|
||||
|
||||
if (!ctx->key_set || ctx->iv_state == IV_STATE_FINISHED)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* FIPS requires generation of AES-GCM IV's inside the FIPS module.
|
||||
* The IV can still be set externally (the security policy will state that
|
||||
* this is not FIPS compliant). There are some applications
|
||||
* where setting the IV externally is the only option available.
|
||||
*/
|
||||
if (ctx->iv_state == IV_STATE_UNINITIALISED) {
|
||||
if (!ctx->enc || !gcm_iv_generate(ctx, 0))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ctx->iv_state == IV_STATE_BUFFERED) {
|
||||
if (!hw->setiv(ctx, ctx->iv, ctx->ivlen))
|
||||
goto err;
|
||||
ctx->iv_state = IV_STATE_COPIED;
|
||||
}
|
||||
|
||||
if (in != NULL) {
|
||||
/* The input is AAD if out is NULL */
|
||||
if (out == NULL) {
|
||||
if (!hw->aadupdate(ctx, in, len))
|
||||
goto err;
|
||||
} else {
|
||||
/* The input is ciphertext OR plaintext */
|
||||
if (!hw->cipherupdate(ctx, in, len, out))
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
/* The tag must be set before actually decrypting data */
|
||||
if (!ctx->enc && ctx->taglen == UNINITIALISED_SIZET)
|
||||
goto err;
|
||||
if (!hw->cipherfinal(ctx, ctx->buf))
|
||||
goto err;
|
||||
ctx->iv_state = IV_STATE_FINISHED; /* Don't reuse the IV */
|
||||
goto finish;
|
||||
}
|
||||
olen = len;
|
||||
finish:
|
||||
rv = 1;
|
||||
err:
|
||||
*padlen = olen;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int gcm_tls_init(PROV_GCM_CTX *dat, unsigned char *aad, size_t aad_len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
size_t len;
|
||||
|
||||
if (aad_len != EVP_AEAD_TLS1_AAD_LEN)
|
||||
return 0;
|
||||
|
||||
/* Save the aad for later use. */
|
||||
buf = dat->buf;
|
||||
memcpy(buf, aad, aad_len);
|
||||
dat->tls_aad_len = aad_len;
|
||||
dat->tls_enc_records = 0;
|
||||
|
||||
len = buf[aad_len - 2] << 8 | buf[aad_len - 1];
|
||||
/* Correct length for explicit iv. */
|
||||
if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN)
|
||||
return 0;
|
||||
len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
||||
|
||||
/* If decrypting correct for tag too. */
|
||||
if (!dat->enc) {
|
||||
if (len < EVP_GCM_TLS_TAG_LEN)
|
||||
return 0;
|
||||
len -= EVP_GCM_TLS_TAG_LEN;
|
||||
}
|
||||
buf[aad_len - 2] = (unsigned char)(len >> 8);
|
||||
buf[aad_len - 1] = (unsigned char)(len & 0xff);
|
||||
/* Extra padding: tag appended to record. */
|
||||
return EVP_GCM_TLS_TAG_LEN;
|
||||
}
|
||||
|
||||
static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv,
|
||||
size_t len)
|
||||
{
|
||||
/* Special case: -1 length restores whole IV */
|
||||
if (len == (size_t)-1) {
|
||||
memcpy(ctx->iv, iv, ctx->ivlen);
|
||||
ctx->iv_gen = 1;
|
||||
ctx->iv_state = IV_STATE_BUFFERED;
|
||||
return 1;
|
||||
}
|
||||
/* Fixed field must be at least 4 bytes and invocation field at least 8 */
|
||||
if ((len < EVP_GCM_TLS_FIXED_IV_LEN)
|
||||
|| (ctx->ivlen - (int)len) < EVP_GCM_TLS_EXPLICIT_IV_LEN)
|
||||
return 0;
|
||||
if (len > 0)
|
||||
memcpy(ctx->iv, iv, len);
|
||||
if (ctx->enc
|
||||
&& rand_bytes_ex(ctx->libctx, ctx->iv + len, ctx->ivlen - len) <= 0)
|
||||
return 0;
|
||||
ctx->iv_gen = 1;
|
||||
ctx->iv_state = IV_STATE_BUFFERED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* increment counter (64-bit int) by 1 */
|
||||
static void ctr64_inc(unsigned char *counter)
|
||||
{
|
||||
int n = 8;
|
||||
unsigned char c;
|
||||
|
||||
do {
|
||||
--n;
|
||||
c = counter[n];
|
||||
++c;
|
||||
counter[n] = c;
|
||||
if (c > 0)
|
||||
return;
|
||||
} while (n > 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle TLS GCM packet format. This consists of the last portion of the IV
|
||||
* followed by the payload and finally the tag. On encrypt generate IV,
|
||||
* encrypt payload and write the tag. On verify retrieve IV, decrypt payload
|
||||
* and verify tag.
|
||||
*/
|
||||
static int gcm_tls_cipher(PROV_GCM_CTX *ctx, unsigned char *out, size_t *padlen,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
int rv = 0;
|
||||
size_t arg = EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
||||
size_t plen = 0;
|
||||
unsigned char *tag = NULL;
|
||||
|
||||
if (!ctx->key_set)
|
||||
goto err;
|
||||
|
||||
/* Encrypt/decrypt must be performed in place */
|
||||
if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Check for too many keys as per FIPS 140-2 IG A.5 "Key/IV Pair Uniqueness
|
||||
* Requirements from SP 800-38D". The requirements is for one party to the
|
||||
* communication to fail after 2^64 - 1 keys. We do this on the encrypting
|
||||
* side only.
|
||||
*/
|
||||
if (ctx->enc && ++ctx->tls_enc_records == 0) {
|
||||
ERR_raise(ERR_LIB_PROV, EVP_R_TOO_MANY_RECORDS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ctx->iv_gen == 0)
|
||||
goto err;
|
||||
/*
|
||||
* Set IV from start of buffer or generate IV and write to start of
|
||||
* buffer.
|
||||
*/
|
||||
if (ctx->enc) {
|
||||
if (!ctx->hw->setiv(ctx, ctx->iv, ctx->ivlen))
|
||||
goto err;
|
||||
if (arg > ctx->ivlen)
|
||||
arg = ctx->ivlen;
|
||||
memcpy(out, ctx->iv + ctx->ivlen - arg, arg);
|
||||
/*
|
||||
* Invocation field will be at least 8 bytes in size and so no need
|
||||
* to check wrap around or increment more than last 8 bytes.
|
||||
*/
|
||||
ctr64_inc(ctx->iv + ctx->ivlen - 8);
|
||||
} else {
|
||||
memcpy(ctx->iv + ctx->ivlen - arg, out, arg);
|
||||
if (!ctx->hw->setiv(ctx, ctx->iv, ctx->ivlen))
|
||||
goto err;
|
||||
}
|
||||
ctx->iv_state = IV_STATE_COPIED;
|
||||
|
||||
/* Fix buffer and length to point to payload */
|
||||
in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
||||
out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
|
||||
len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
|
||||
|
||||
tag = ctx->enc ? out + len : (unsigned char *)in + len;
|
||||
if (!ctx->hw->oneshot(ctx, ctx->buf, ctx->tls_aad_len, in, len, out, tag,
|
||||
EVP_GCM_TLS_TAG_LEN)) {
|
||||
if (!ctx->enc)
|
||||
OPENSSL_cleanse(out, len);
|
||||
goto err;
|
||||
}
|
||||
if (ctx->enc)
|
||||
plen = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
|
||||
else
|
||||
plen = len;
|
||||
|
||||
rv = 1;
|
||||
err:
|
||||
ctx->iv_state = IV_STATE_FINISHED;
|
||||
ctx->tls_aad_len = UNINITIALISED_SIZET;
|
||||
*padlen = plen;
|
||||
return rv;
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "prov/ciphercommon.h"
|
||||
#include "prov/cipher_gcm.h"
|
||||
|
||||
|
||||
int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
CRYPTO_gcm128_setiv(&ctx->gcm, iv, ivlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad, size_t aad_len)
|
||||
{
|
||||
return CRYPTO_gcm128_aad(&ctx->gcm, aad, aad_len) == 0;
|
||||
}
|
||||
|
||||
int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
|
||||
size_t len, unsigned char *out)
|
||||
{
|
||||
if (ctx->enc) {
|
||||
if (ctx->ctr != NULL) {
|
||||
#if defined(AES_GCM_ASM)
|
||||
size_t bulk = 0;
|
||||
|
||||
if (len >= 32 && AES_GCM_ASM(ctx)) {
|
||||
size_t res = (16 - ctx->gcm.mres) % 16;
|
||||
|
||||
if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, res))
|
||||
return 0;
|
||||
bulk = aesni_gcm_encrypt(in + res, out + res, len - res,
|
||||
ctx->gcm.key,
|
||||
ctx->gcm.Yi.c, ctx->gcm.Xi.u);
|
||||
ctx->gcm.len.u[1] += bulk;
|
||||
bulk += res;
|
||||
}
|
||||
if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in + bulk, out + bulk,
|
||||
len - bulk, ctx->ctr))
|
||||
return 0;
|
||||
#else
|
||||
if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr))
|
||||
return 0;
|
||||
#endif /* AES_GCM_ASM */
|
||||
} else {
|
||||
if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, len))
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (ctx->ctr != NULL) {
|
||||
#if defined(AES_GCM_ASM)
|
||||
size_t bulk = 0;
|
||||
|
||||
if (len >= 16 && AES_GCM_ASM(ctx)) {
|
||||
size_t res = (16 - ctx->gcm.mres) % 16;
|
||||
|
||||
if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, res))
|
||||
return -1;
|
||||
|
||||
bulk = aesni_gcm_decrypt(in + res, out + res, len - res,
|
||||
ctx->gcm.key,
|
||||
ctx->gcm.Yi.c, ctx->gcm.Xi.u);
|
||||
ctx->gcm.len.u[1] += bulk;
|
||||
bulk += res;
|
||||
}
|
||||
if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in + bulk, out + bulk,
|
||||
len - bulk, ctx->ctr))
|
||||
return 0;
|
||||
#else
|
||||
if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr))
|
||||
return 0;
|
||||
#endif /* AES_GCM_ASM */
|
||||
} else {
|
||||
if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, len))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag)
|
||||
{
|
||||
if (ctx->enc) {
|
||||
CRYPTO_gcm128_tag(&ctx->gcm, tag, GCM_TAG_MAX_SIZE);
|
||||
ctx->taglen = GCM_TAG_MAX_SIZE;
|
||||
} else {
|
||||
if (CRYPTO_gcm128_finish(&ctx->gcm, tag, ctx->taglen) != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len,
|
||||
const unsigned char *in, size_t in_len,
|
||||
unsigned char *out, unsigned char *tag, size_t tag_len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Use saved AAD */
|
||||
if (!ctx->hw->aadupdate(ctx, aad, aad_len))
|
||||
goto err;
|
||||
if (!ctx->hw->cipherupdate(ctx, in, in_len, out))
|
||||
goto err;
|
||||
ctx->taglen = GCM_TAG_MAX_SIZE;
|
||||
if (!ctx->hw->cipherfinal(ctx, tag))
|
||||
goto err;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "prov/ciphercommon.h"
|
||||
|
||||
void padblock(unsigned char *buf, size_t *buflen, size_t blocksize);
|
||||
int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize);
|
||||
@@ -1,2 +0,0 @@
|
||||
# This source is common for all digests in all our providers.
|
||||
SOURCE[../../libcommon.a]=digest_common.c
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "openssl/err.h"
|
||||
#include "prov/digestcommon.h"
|
||||
#include "prov/providercommonerr.h"
|
||||
|
||||
int digest_default_get_params(OSSL_PARAM params[], size_t blksz, size_t paramsz,
|
||||
unsigned long flags)
|
||||
{
|
||||
OSSL_PARAM *p = NULL;
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_BLOCK_SIZE);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, blksz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE);
|
||||
if (p != NULL && !OSSL_PARAM_set_size_t(p, paramsz)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_FLAGS);
|
||||
if (p != NULL && !OSSL_PARAM_set_ulong(p, flags)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const OSSL_PARAM digest_default_known_gettable_params[] = {
|
||||
OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, NULL),
|
||||
OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_SIZE, NULL),
|
||||
OSSL_PARAM_ulong(OSSL_DIGEST_PARAM_FLAGS, NULL),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
const OSSL_PARAM *digest_default_gettable_params(void)
|
||||
{
|
||||
return digest_default_known_gettable_params;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/core.h>
|
||||
|
||||
int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns);
|
||||
|
||||
BIO *ossl_prov_bio_new_file(const char *filename, const char *mode);
|
||||
BIO *ossl_prov_bio_new_membuf(const char *filename, int len);
|
||||
int ossl_prov_bio_read_ex(BIO *bio, void *data, size_t data_len,
|
||||
size_t *bytes_read);
|
||||
int ossl_prov_bio_free(BIO *bio);
|
||||
int ossl_prov_bio_vprintf(BIO *bio, const char *format, va_list ap);
|
||||
int ossl_prov_bio_printf(BIO *bio, const char *format, ...);
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#define UNINITIALISED_SIZET ((size_t)-1)
|
||||
|
||||
/* TODO(3.0) Figure out what flags are really needed */
|
||||
#define AEAD_FLAGS (EVP_CIPH_FLAG_AEAD_CIPHER \
|
||||
| EVP_CIPH_CUSTOM_IV \
|
||||
| EVP_CIPH_ALWAYS_CALL_INIT \
|
||||
| EVP_CIPH_CTRL_INIT \
|
||||
| EVP_CIPH_CUSTOM_COPY)
|
||||
|
||||
#define IMPLEMENT_aead_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits) \
|
||||
static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \
|
||||
static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \
|
||||
{ \
|
||||
return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \
|
||||
flags, kbits, blkbits, ivbits); \
|
||||
} \
|
||||
static OSSL_OP_cipher_newctx_fn alg##kbits##lc##_newctx; \
|
||||
static void * alg##kbits##lc##_newctx(void *provctx) \
|
||||
{ \
|
||||
return alg##_##lc##_newctx(provctx, kbits); \
|
||||
} \
|
||||
const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \
|
||||
{ OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \
|
||||
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \
|
||||
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit }, \
|
||||
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) lc##_dinit }, \
|
||||
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void)) lc##_stream_update }, \
|
||||
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void)) lc##_stream_final }, \
|
||||
{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void)) lc##_cipher }, \
|
||||
{ OSSL_FUNC_CIPHER_GET_PARAMS, \
|
||||
(void (*)(void)) alg##_##kbits##_##lc##_get_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \
|
||||
(void (*)(void)) lc##_get_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \
|
||||
(void (*)(void)) lc##_set_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \
|
||||
(void (*)(void))cipher_generic_gettable_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_aead_gettable_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_aead_settable_ctx_params }, \
|
||||
{ 0, NULL } \
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "cipher_aead.h"
|
||||
|
||||
typedef struct prov_ccm_hw_st PROV_CCM_HW;
|
||||
|
||||
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
|
||||
/*-
|
||||
* KMAC-AES parameter block - begin
|
||||
* (see z/Architecture Principles of Operation >= SA22-7832-08)
|
||||
*/
|
||||
typedef struct S390X_kmac_params_st {
|
||||
union {
|
||||
unsigned long long g[2];
|
||||
unsigned char b[16];
|
||||
} icv;
|
||||
unsigned char k[32];
|
||||
} S390X_KMAC_PARAMS;
|
||||
/* KMAC-AES parameter block - end */
|
||||
#endif
|
||||
|
||||
/* Base structure that is shared by AES & ARIA for CCM MODE */
|
||||
typedef struct prov_ccm_st {
|
||||
unsigned int enc : 1;
|
||||
unsigned int key_set : 1; /* Set if key initialised */
|
||||
unsigned int iv_set : 1; /* Set if an iv is set */
|
||||
unsigned int tag_set : 1; /* Set if tag is valid */
|
||||
unsigned int len_set : 1; /* Set if message length set */
|
||||
size_t l, m; /* L and M parameters from RFC3610 */
|
||||
size_t keylen;
|
||||
size_t tls_aad_len; /* TLS AAD length */
|
||||
size_t tls_aad_pad_sz;
|
||||
unsigned char iv[AES_BLOCK_SIZE];
|
||||
unsigned char buf[AES_BLOCK_SIZE];
|
||||
CCM128_CONTEXT ccm_ctx;
|
||||
ccm128_f str;
|
||||
const PROV_CCM_HW *hw; /* hardware specific methods */
|
||||
} PROV_CCM_CTX;
|
||||
|
||||
typedef struct prov_aes_ccm_ctx_st {
|
||||
PROV_CCM_CTX base; /* Must be first */
|
||||
union {
|
||||
OSSL_UNION_ALIGN;
|
||||
/*-
|
||||
* Padding is chosen so that s390x.kmac.k overlaps with ks.ks and
|
||||
* fc with ks.ks.rounds. Remember that on s390x, an AES_KEY's
|
||||
* rounds field is used to store the function code and that the key
|
||||
* schedule is not stored (if aes hardware support is detected).
|
||||
*/
|
||||
struct {
|
||||
unsigned char pad[16];
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
|
||||
struct {
|
||||
S390X_KMAC_PARAMS kmac;
|
||||
unsigned long long blocks;
|
||||
union {
|
||||
unsigned long long g[2];
|
||||
unsigned char b[AES_BLOCK_SIZE];
|
||||
} nonce;
|
||||
union {
|
||||
unsigned long long g[2];
|
||||
unsigned char b[AES_BLOCK_SIZE];
|
||||
} buf;
|
||||
unsigned char dummy_pad[168];
|
||||
unsigned int fc; /* fc has same offset as ks.ks.rounds */
|
||||
} s390x;
|
||||
#endif /* defined(OPENSSL_CPUID_OBJ) && defined(__s390__) */
|
||||
} ccm;
|
||||
} PROV_AES_CCM_CTX;
|
||||
|
||||
PROV_CIPHER_FUNC(int, CCM_cipher, (PROV_CCM_CTX *ctx, unsigned char *out, \
|
||||
size_t *padlen, const unsigned char *in, \
|
||||
size_t len));
|
||||
PROV_CIPHER_FUNC(int, CCM_setkey, (PROV_CCM_CTX *ctx, \
|
||||
const unsigned char *key, size_t keylen));
|
||||
PROV_CIPHER_FUNC(int, CCM_setiv, (PROV_CCM_CTX *dat, \
|
||||
const unsigned char *iv, size_t ivlen, \
|
||||
size_t mlen));
|
||||
PROV_CIPHER_FUNC(int, CCM_setaad, (PROV_CCM_CTX *ctx, \
|
||||
const unsigned char *aad, size_t aadlen));
|
||||
PROV_CIPHER_FUNC(int, CCM_auth_encrypt, (PROV_CCM_CTX *ctx, \
|
||||
const unsigned char *in, \
|
||||
unsigned char *out, size_t len, \
|
||||
unsigned char *tag, size_t taglen));
|
||||
PROV_CIPHER_FUNC(int, CCM_auth_decrypt, (PROV_CCM_CTX *ctx, \
|
||||
const unsigned char *in, \
|
||||
unsigned char *out, size_t len, \
|
||||
unsigned char *tag, size_t taglen));
|
||||
PROV_CIPHER_FUNC(int, CCM_gettag, (PROV_CCM_CTX *ctx, \
|
||||
unsigned char *tag, size_t taglen));
|
||||
|
||||
/*
|
||||
* CCM Mode internal method table used to handle hardware specific differences,
|
||||
* (and different algorithms).
|
||||
*/
|
||||
struct prov_ccm_hw_st {
|
||||
OSSL_CCM_setkey_fn setkey;
|
||||
OSSL_CCM_setiv_fn setiv;
|
||||
OSSL_CCM_setaad_fn setaad;
|
||||
OSSL_CCM_auth_encrypt_fn auth_encrypt;
|
||||
OSSL_CCM_auth_decrypt_fn auth_decrypt;
|
||||
OSSL_CCM_gettag_fn gettag;
|
||||
};
|
||||
|
||||
const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keylen);
|
||||
|
||||
OSSL_OP_cipher_encrypt_init_fn ccm_einit;
|
||||
OSSL_OP_cipher_decrypt_init_fn ccm_dinit;
|
||||
OSSL_OP_cipher_get_ctx_params_fn ccm_get_ctx_params;
|
||||
OSSL_OP_cipher_set_ctx_params_fn ccm_set_ctx_params;
|
||||
OSSL_OP_cipher_update_fn ccm_stream_update;
|
||||
OSSL_OP_cipher_final_fn ccm_stream_final;
|
||||
OSSL_OP_cipher_cipher_fn ccm_cipher;
|
||||
void ccm_initctx(PROV_CCM_CTX *ctx, size_t keybits, const PROV_CCM_HW *hw);
|
||||
|
||||
int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
|
||||
size_t nlen, size_t mlen);
|
||||
int ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad, size_t alen);
|
||||
int ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag, size_t tlen);
|
||||
int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
unsigned char *tag, size_t taglen);
|
||||
int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
unsigned char *expected_tag, size_t taglen);
|
||||
@@ -1,160 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include "cipher_aead.h"
|
||||
|
||||
typedef struct prov_gcm_hw_st PROV_GCM_HW;
|
||||
|
||||
#define GCM_IV_DEFAULT_SIZE 12 /* IV's for AES_GCM should normally be 12 bytes */
|
||||
#define GCM_IV_MAX_SIZE 64
|
||||
#define GCM_TAG_MAX_SIZE 16
|
||||
|
||||
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
|
||||
/*-
|
||||
* KMA-GCM-AES parameter block - begin
|
||||
* (see z/Architecture Principles of Operation >= SA22-7832-11)
|
||||
*/
|
||||
typedef struct S390X_kma_params_st {
|
||||
unsigned char reserved[12];
|
||||
union {
|
||||
unsigned int w;
|
||||
unsigned char b[4];
|
||||
} cv; /* 32 bit counter value */
|
||||
union {
|
||||
unsigned long long g[2];
|
||||
unsigned char b[16];
|
||||
} t; /* tag */
|
||||
unsigned char h[16]; /* hash subkey */
|
||||
unsigned long long taadl; /* total AAD length */
|
||||
unsigned long long tpcl; /* total plaintxt/ciphertxt len */
|
||||
union {
|
||||
unsigned long long g[2];
|
||||
unsigned int w[4];
|
||||
} j0; /* initial counter value */
|
||||
unsigned char k[32]; /* key */
|
||||
} S390X_KMA_PARAMS;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct prov_gcm_ctx_st {
|
||||
unsigned int mode; /* The mode that we are using */
|
||||
size_t keylen;
|
||||
size_t ivlen;
|
||||
size_t ivlen_min;
|
||||
size_t taglen;
|
||||
size_t tls_aad_pad_sz;
|
||||
size_t tls_aad_len; /* TLS AAD length */
|
||||
uint64_t tls_enc_records; /* Number of TLS records encrypted */
|
||||
|
||||
/*
|
||||
* num contains the number of bytes of |iv| which are valid for modes that
|
||||
* manage partial blocks themselves.
|
||||
*/
|
||||
size_t num;
|
||||
size_t bufsz; /* Number of bytes in buf */
|
||||
uint64_t flags;
|
||||
|
||||
unsigned int iv_state; /* set to one of IV_STATE_XXX */
|
||||
unsigned int enc:1; /* Set to 1 if we are encrypting or 0 otherwise */
|
||||
unsigned int pad:1; /* Whether padding should be used or not */
|
||||
unsigned int key_set:1; /* Set if key initialised */
|
||||
unsigned int iv_gen_rand:1; /* No IV was specified, so generate a rand IV */
|
||||
unsigned int iv_gen:1; /* It is OK to generate IVs */
|
||||
|
||||
unsigned char iv[GCM_IV_MAX_SIZE]; /* Buffer to use for IV's */
|
||||
unsigned char buf[AES_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */
|
||||
|
||||
OPENSSL_CTX *libctx; /* needed for rand calls */
|
||||
const PROV_GCM_HW *hw; /* hardware specific methods */
|
||||
GCM128_CONTEXT gcm;
|
||||
ctr128_f ctr;
|
||||
const void *ks;
|
||||
} PROV_GCM_CTX;
|
||||
|
||||
typedef struct prov_aes_gcm_ctx_st {
|
||||
PROV_GCM_CTX base; /* must be first entry in struct */
|
||||
union {
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ks; /* AES key schedule to use */
|
||||
|
||||
/* Platform specific data */
|
||||
union {
|
||||
int dummy;
|
||||
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
|
||||
struct {
|
||||
union {
|
||||
OSSL_UNION_ALIGN;
|
||||
S390X_KMA_PARAMS kma;
|
||||
} param;
|
||||
unsigned int fc;
|
||||
unsigned char ares[16];
|
||||
unsigned char mres[16];
|
||||
unsigned char kres[16];
|
||||
int areslen;
|
||||
int mreslen;
|
||||
int kreslen;
|
||||
int res;
|
||||
} s390x;
|
||||
#endif /* defined(OPENSSL_CPUID_OBJ) && defined(__s390__) */
|
||||
} plat;
|
||||
} PROV_AES_GCM_CTX;
|
||||
|
||||
PROV_CIPHER_FUNC(int, GCM_setkey, (PROV_GCM_CTX *ctx, const unsigned char *key,
|
||||
size_t keylen));
|
||||
PROV_CIPHER_FUNC(int, GCM_setiv, (PROV_GCM_CTX *dat, const unsigned char *iv,
|
||||
size_t ivlen));
|
||||
PROV_CIPHER_FUNC(int, GCM_aadupdate, (PROV_GCM_CTX *ctx,
|
||||
const unsigned char *aad, size_t aadlen));
|
||||
PROV_CIPHER_FUNC(int, GCM_cipherupdate, (PROV_GCM_CTX *ctx,
|
||||
const unsigned char *in, size_t len,
|
||||
unsigned char *out));
|
||||
PROV_CIPHER_FUNC(int, GCM_cipherfinal, (PROV_GCM_CTX *ctx, unsigned char *tag));
|
||||
PROV_CIPHER_FUNC(int, GCM_oneshot, (PROV_GCM_CTX *ctx, unsigned char *aad,
|
||||
size_t aad_len, const unsigned char *in,
|
||||
size_t in_len, unsigned char *out,
|
||||
unsigned char *tag, size_t taglen));
|
||||
struct prov_gcm_hw_st {
|
||||
OSSL_GCM_setkey_fn setkey;
|
||||
OSSL_GCM_setiv_fn setiv;
|
||||
OSSL_GCM_aadupdate_fn aadupdate;
|
||||
OSSL_GCM_cipherupdate_fn cipherupdate;
|
||||
OSSL_GCM_cipherfinal_fn cipherfinal;
|
||||
OSSL_GCM_oneshot_fn oneshot;
|
||||
};
|
||||
const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits);
|
||||
|
||||
OSSL_OP_cipher_encrypt_init_fn gcm_einit;
|
||||
OSSL_OP_cipher_decrypt_init_fn gcm_dinit;
|
||||
OSSL_OP_cipher_get_ctx_params_fn gcm_get_ctx_params;
|
||||
OSSL_OP_cipher_set_ctx_params_fn gcm_set_ctx_params;
|
||||
OSSL_OP_cipher_cipher_fn gcm_cipher;
|
||||
OSSL_OP_cipher_update_fn gcm_stream_update;
|
||||
OSSL_OP_cipher_final_fn gcm_stream_final;
|
||||
void gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits,
|
||||
const PROV_GCM_HW *hw, size_t ivlen_min);
|
||||
|
||||
int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen);
|
||||
int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad,
|
||||
size_t aad_len);
|
||||
int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag);
|
||||
int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len,
|
||||
const unsigned char *in, size_t in_len,
|
||||
unsigned char *out, unsigned char *tag, size_t tag_len);
|
||||
int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in,
|
||||
size_t len, unsigned char *out);
|
||||
|
||||
#define GCM_HW_SET_KEY_CTR_FN(ks, fn_set_enc_key, fn_block, fn_ctr) \
|
||||
ctx->ks = ks; \
|
||||
fn_set_enc_key(key, keylen * 8, ks); \
|
||||
CRYPTO_gcm128_init(&ctx->gcm, ks, (block128_f)fn_block); \
|
||||
ctx->ctr = (ctr128_f)fn_ctr; \
|
||||
ctx->key_set = 1;
|
||||
@@ -1,272 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/core_numbers.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "crypto/modes.h"
|
||||
#include "crypto/ciphermode_platform.h"
|
||||
|
||||
#define MAXCHUNK ((size_t)1 << (sizeof(long) * 8 - 2))
|
||||
#define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4))
|
||||
|
||||
#define GENERIC_BLOCK_SIZE 16
|
||||
#define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */
|
||||
#define IV_STATE_BUFFERED 1 /* iv has been copied to the iv buffer */
|
||||
#define IV_STATE_COPIED 2 /* iv has been copied from the iv buffer */
|
||||
#define IV_STATE_FINISHED 3 /* the iv has been used - so don't reuse it */
|
||||
|
||||
#define PROV_CIPHER_FUNC(type, name, args) typedef type (* OSSL_##name##_fn)args
|
||||
|
||||
typedef struct prov_cipher_hw_st PROV_CIPHER_HW;
|
||||
typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX;
|
||||
|
||||
typedef int (PROV_CIPHER_HW_FN)(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len);
|
||||
|
||||
struct prov_cipher_ctx_st {
|
||||
block128_f block;
|
||||
union {
|
||||
cbc128_f cbc;
|
||||
ctr128_f ctr;
|
||||
} stream;
|
||||
|
||||
unsigned int mode;
|
||||
size_t keylen; /* key size (in bytes) */
|
||||
size_t ivlen;
|
||||
size_t blocksize;
|
||||
size_t bufsz; /* Number of bytes in buf */
|
||||
unsigned int pad : 1; /* Whether padding should be used or not */
|
||||
unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */
|
||||
unsigned int iv_set : 1; /* Set when the iv is copied to the iv/oiv buffers */
|
||||
|
||||
/*
|
||||
* num contains the number of bytes of |iv| which are valid for modes that
|
||||
* manage partial blocks themselves.
|
||||
*/
|
||||
unsigned int num;
|
||||
uint64_t flags;
|
||||
|
||||
/* The original value of the iv */
|
||||
unsigned char oiv[GENERIC_BLOCK_SIZE];
|
||||
/* Buffer of partial blocks processed via update calls */
|
||||
unsigned char buf[GENERIC_BLOCK_SIZE];
|
||||
unsigned char iv[GENERIC_BLOCK_SIZE];
|
||||
const PROV_CIPHER_HW *hw; /* hardware specific functions */
|
||||
const void *ks; /* Pointer to algorithm specific key data */
|
||||
OPENSSL_CTX *libctx;
|
||||
};
|
||||
|
||||
struct prov_cipher_hw_st {
|
||||
int (*init)(PROV_CIPHER_CTX *dat, const uint8_t *key, size_t keylen);
|
||||
PROV_CIPHER_HW_FN *cipher;
|
||||
};
|
||||
|
||||
OSSL_OP_cipher_encrypt_init_fn cipher_generic_einit;
|
||||
OSSL_OP_cipher_decrypt_init_fn cipher_generic_dinit;
|
||||
OSSL_OP_cipher_update_fn cipher_generic_block_update;
|
||||
OSSL_OP_cipher_final_fn cipher_generic_block_final;
|
||||
OSSL_OP_cipher_update_fn cipher_generic_stream_update;
|
||||
OSSL_OP_cipher_final_fn cipher_generic_stream_final;
|
||||
OSSL_OP_cipher_cipher_fn cipher_generic_cipher;
|
||||
OSSL_OP_cipher_get_ctx_params_fn cipher_generic_get_ctx_params;
|
||||
OSSL_OP_cipher_set_ctx_params_fn cipher_generic_set_ctx_params;
|
||||
OSSL_OP_cipher_gettable_params_fn cipher_generic_gettable_params;
|
||||
OSSL_OP_cipher_gettable_ctx_params_fn cipher_generic_gettable_ctx_params;
|
||||
OSSL_OP_cipher_settable_ctx_params_fn cipher_generic_settable_ctx_params;
|
||||
OSSL_OP_cipher_gettable_ctx_params_fn cipher_aead_gettable_ctx_params;
|
||||
OSSL_OP_cipher_settable_ctx_params_fn cipher_aead_settable_ctx_params;
|
||||
int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
|
||||
unsigned long flags,
|
||||
size_t kbits, size_t blkbits, size_t ivbits);
|
||||
void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
|
||||
size_t ivbits, unsigned int mode, uint64_t flags,
|
||||
const PROV_CIPHER_HW *hw, void *provctx);
|
||||
|
||||
#define IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits,\
|
||||
blkbits, ivbits, typ) \
|
||||
const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \
|
||||
{ OSSL_FUNC_CIPHER_NEWCTX, \
|
||||
(void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \
|
||||
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \
|
||||
{ OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \
|
||||
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \
|
||||
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \
|
||||
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\
|
||||
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final }, \
|
||||
{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \
|
||||
{ OSSL_FUNC_CIPHER_GET_PARAMS, \
|
||||
(void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_generic_get_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_generic_set_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \
|
||||
(void (*)(void))cipher_generic_gettable_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_generic_gettable_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_generic_settable_ctx_params }, \
|
||||
{ 0, NULL } \
|
||||
};
|
||||
|
||||
#define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \
|
||||
blkbits, ivbits, typ) \
|
||||
static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \
|
||||
static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \
|
||||
{ \
|
||||
return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \
|
||||
kbits, blkbits, ivbits); \
|
||||
} \
|
||||
static OSSL_OP_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \
|
||||
static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \
|
||||
{ \
|
||||
PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
|
||||
if (ctx != NULL) { \
|
||||
cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \
|
||||
EVP_CIPH_##UCMODE##_MODE, flags, \
|
||||
PROV_CIPHER_HW_##alg##_##lcmode(kbits), NULL); \
|
||||
} \
|
||||
return ctx; \
|
||||
} \
|
||||
IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \
|
||||
blkbits, ivbits, typ)
|
||||
|
||||
PROV_CIPHER_HW_FN cipher_hw_generic_cbc;
|
||||
PROV_CIPHER_HW_FN cipher_hw_generic_ecb;
|
||||
PROV_CIPHER_HW_FN cipher_hw_generic_ofb128;
|
||||
PROV_CIPHER_HW_FN cipher_hw_generic_cfb128;
|
||||
PROV_CIPHER_HW_FN cipher_hw_generic_cfb8;
|
||||
PROV_CIPHER_HW_FN cipher_hw_generic_cfb1;
|
||||
PROV_CIPHER_HW_FN cipher_hw_generic_ctr;
|
||||
PROV_CIPHER_HW_FN cipher_hw_chunked_cbc;
|
||||
PROV_CIPHER_HW_FN cipher_hw_chunked_cfb8;
|
||||
PROV_CIPHER_HW_FN cipher_hw_chunked_cfb128;
|
||||
PROV_CIPHER_HW_FN cipher_hw_chunked_ofb128;
|
||||
#define cipher_hw_chunked_ecb cipher_hw_generic_ecb
|
||||
#define cipher_hw_chunked_ctr cipher_hw_generic_ctr
|
||||
#define cipher_hw_chunked_cfb1 cipher_hw_generic_cfb1
|
||||
|
||||
#define IMPLEMENT_CIPHER_HW_OFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \
|
||||
static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \
|
||||
unsigned char *out, \
|
||||
const unsigned char *in, size_t len) \
|
||||
{ \
|
||||
int num = ctx->num; \
|
||||
KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \
|
||||
\
|
||||
while (len >= MAXCHUNK) { \
|
||||
FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, &num); \
|
||||
len -= MAXCHUNK; \
|
||||
in += MAXCHUNK; \
|
||||
out += MAXCHUNK; \
|
||||
} \
|
||||
if (len > 0) { \
|
||||
FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, &num); \
|
||||
} \
|
||||
ctx->num = num; \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define IMPLEMENT_CIPHER_HW_ECB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \
|
||||
static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \
|
||||
unsigned char *out, \
|
||||
const unsigned char *in, size_t len) \
|
||||
{ \
|
||||
size_t i, bl = ctx->blocksize; \
|
||||
KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \
|
||||
\
|
||||
if (len < bl) \
|
||||
return 1; \
|
||||
for (i = 0, len -= bl; i <= len; i += bl) \
|
||||
FUNC_PREFIX##_encrypt(in + i, out + i, key, ctx->enc); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define IMPLEMENT_CIPHER_HW_CBC(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \
|
||||
static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \
|
||||
unsigned char *out, \
|
||||
const unsigned char *in, size_t len) \
|
||||
{ \
|
||||
KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \
|
||||
\
|
||||
while (len >= MAXCHUNK) { \
|
||||
FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, ctx->enc); \
|
||||
len -= MAXCHUNK; \
|
||||
in += MAXCHUNK; \
|
||||
out += MAXCHUNK; \
|
||||
} \
|
||||
if (len > 0) \
|
||||
FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, ctx->enc); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define IMPLEMENT_CIPHER_HW_CFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \
|
||||
static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \
|
||||
unsigned char *out, \
|
||||
const unsigned char *in, size_t len) \
|
||||
{ \
|
||||
size_t chunk = MAXCHUNK; \
|
||||
KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \
|
||||
int num = ctx->num; \
|
||||
\
|
||||
if (len < chunk) \
|
||||
chunk = len; \
|
||||
while (len > 0 && len >= chunk) { \
|
||||
FUNC_PREFIX##_encrypt(in, out, (long)chunk, key, ctx->iv, &num, \
|
||||
ctx->enc); \
|
||||
len -= chunk; \
|
||||
in += chunk; \
|
||||
out += chunk; \
|
||||
if (len < chunk) \
|
||||
chunk = len; \
|
||||
} \
|
||||
ctx->num = num; \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \
|
||||
static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \
|
||||
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \
|
||||
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), \
|
||||
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
|
||||
|
||||
#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \
|
||||
OSSL_PARAM_END \
|
||||
}; \
|
||||
const OSSL_PARAM * name##_gettable_ctx_params(void) \
|
||||
{ \
|
||||
return name##_known_gettable_ctx_params; \
|
||||
}
|
||||
|
||||
#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(name) \
|
||||
static const OSSL_PARAM name##_known_settable_ctx_params[] = { \
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \
|
||||
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \
|
||||
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL),
|
||||
#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(name) \
|
||||
OSSL_PARAM_END \
|
||||
}; \
|
||||
const OSSL_PARAM * name##_settable_ctx_params(void) \
|
||||
{ \
|
||||
return name##_known_settable_ctx_params; \
|
||||
}
|
||||
|
||||
int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
|
||||
size_t ivlen);
|
||||
|
||||
size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
|
||||
const unsigned char **in, size_t *inlen);
|
||||
int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
|
||||
const unsigned char **in, size_t *inlen);
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#ifndef OSSL_PROVIDERS_DIGESTCOMMON_H
|
||||
# define OSSL_PROVIDERS_DIGESTCOMMON_H
|
||||
|
||||
# include <openssl/core_numbers.h>
|
||||
# include <openssl/core_names.h>
|
||||
# include <openssl/params.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
#define PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \
|
||||
static OSSL_OP_digest_get_params_fn name##_get_params; \
|
||||
static int name##_get_params(OSSL_PARAM params[]) \
|
||||
{ \
|
||||
return digest_default_get_params(params, blksize, dgstsize, flags); \
|
||||
}
|
||||
|
||||
#define PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name) \
|
||||
{ OSSL_FUNC_DIGEST_GET_PARAMS, (void (*)(void))name##_get_params }, \
|
||||
{ OSSL_FUNC_DIGEST_GETTABLE_PARAMS, \
|
||||
(void (*)(void))digest_default_gettable_params }
|
||||
|
||||
# define PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_START( \
|
||||
name, CTX, blksize, dgstsize, flags, init, upd, fin) \
|
||||
static OSSL_OP_digest_newctx_fn name##_newctx; \
|
||||
static OSSL_OP_digest_freectx_fn name##_freectx; \
|
||||
static OSSL_OP_digest_dupctx_fn name##_dupctx; \
|
||||
static void *name##_newctx(void *prov_ctx) \
|
||||
{ \
|
||||
CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
|
||||
return ctx; \
|
||||
} \
|
||||
static void name##_freectx(void *vctx) \
|
||||
{ \
|
||||
CTX *ctx = (CTX *)vctx; \
|
||||
OPENSSL_clear_free(ctx, sizeof(*ctx)); \
|
||||
} \
|
||||
static void *name##_dupctx(void *ctx) \
|
||||
{ \
|
||||
CTX *in = (CTX *)ctx; \
|
||||
CTX *ret = OPENSSL_malloc(sizeof(*ret)); \
|
||||
*ret = *in; \
|
||||
return ret; \
|
||||
} \
|
||||
static OSSL_OP_digest_final_fn name##_internal_final; \
|
||||
static int name##_internal_final(void *ctx, unsigned char *out, size_t *outl, \
|
||||
size_t outsz) \
|
||||
{ \
|
||||
if (outsz >= dgstsize && fin(out, ctx)) { \
|
||||
*outl = dgstsize; \
|
||||
return 1; \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \
|
||||
const OSSL_DISPATCH name##_functions[] = { \
|
||||
{ OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \
|
||||
{ OSSL_FUNC_DIGEST_INIT, (void (*)(void))init }, \
|
||||
{ OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))upd }, \
|
||||
{ OSSL_FUNC_DIGEST_FINAL, (void (*)(void))name##_internal_final }, \
|
||||
{ OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))name##_freectx }, \
|
||||
{ OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))name##_dupctx }, \
|
||||
PROV_DISPATCH_FUNC_DIGEST_GET_PARAMS(name)
|
||||
|
||||
# define PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END \
|
||||
{ 0, NULL } \
|
||||
};
|
||||
|
||||
# define IMPLEMENT_digest_functions( \
|
||||
name, CTX, blksize, dgstsize, flags, init, upd, fin) \
|
||||
PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_START(name, CTX, blksize, dgstsize, flags, \
|
||||
init, upd, fin), \
|
||||
PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
|
||||
|
||||
# define IMPLEMENT_digest_functions_with_settable_ctx( \
|
||||
name, CTX, blksize, dgstsize, flags, init, upd, fin, \
|
||||
settable_ctx_params, set_ctx_params) \
|
||||
PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_START(name, CTX, blksize, dgstsize, flags, \
|
||||
init, upd, fin), \
|
||||
{ OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, (void (*)(void))settable_ctx_params }, \
|
||||
{ OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))set_ctx_params }, \
|
||||
PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END
|
||||
|
||||
|
||||
const OSSL_PARAM *digest_default_gettable_params(void);
|
||||
int digest_default_get_params(OSSL_PARAM params[], size_t blksz, size_t paramsz,
|
||||
unsigned long flags);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* OSSL_PROVIDERS_DIGESTCOMMON_H */
|
||||
@@ -101,3 +101,15 @@ int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
|
||||
const char *ciphername,
|
||||
const char *mdname,
|
||||
OPENSSL_CTX *ctx);
|
||||
|
||||
typedef struct ag_capable_st {
|
||||
OSSL_ALGORITHM alg;
|
||||
int (*capable)(void);
|
||||
} OSSL_ALGORITHM_CAPABLE;
|
||||
|
||||
/*
|
||||
* Dynamically select algorithms by calling a capable() method.
|
||||
* If this method is NULL or the method returns 1 then the algorithm is added.
|
||||
*/
|
||||
void ossl_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in,
|
||||
OSSL_ALGORITHM *out);
|
||||
@@ -13,3 +13,5 @@ const OSSL_PROVIDER *FIPS_get_provider(OPENSSL_CTX *ctx);
|
||||
|
||||
const char *ossl_prov_util_nid_to_name(int nid);
|
||||
|
||||
int cipher_capable_aes_cbc_hmac_sha1(void);
|
||||
int cipher_capable_aes_cbc_hmac_sha256(void);
|
||||
@@ -23,7 +23,7 @@ int ERR_load_PROV_strings(void);
|
||||
/*
|
||||
* PROV function codes.
|
||||
*/
|
||||
# if !OPENSSL_API_3
|
||||
# ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
# define PROV_F_AESNI_INIT_KEY 0
|
||||
# define PROV_F_AES_BLOCK_FINAL 0
|
||||
# define PROV_F_AES_BLOCK_UPDATE 0
|
||||
@@ -53,19 +53,24 @@ int ERR_load_PROV_strings(void);
|
||||
# define PROV_R_BAD_DECRYPT 100
|
||||
# define PROV_R_BAD_ENCODING 141
|
||||
# define PROV_R_BAD_LENGTH 142
|
||||
# define PROV_R_BAD_TLS_CLIENT_VERSION 161
|
||||
# define PROV_R_BN_ERROR 160
|
||||
# define PROV_R_BOTH_MODE_AND_MODE_INT 127
|
||||
# define PROV_R_CIPHER_OPERATION_FAILED 102
|
||||
# define PROV_R_FAILED_TO_DECRYPT 162
|
||||
# define PROV_R_FAILED_TO_GENERATE_KEY 121
|
||||
# define PROV_R_FAILED_TO_GET_PARAMETER 103
|
||||
# define PROV_R_FAILED_TO_SET_PARAMETER 104
|
||||
# define PROV_R_INAVLID_UKM_LENGTH 146
|
||||
# define PROV_R_INVALID_AAD 108
|
||||
# define PROV_R_INVALID_CONSTANT_LENGTH 157
|
||||
# define PROV_R_INVALID_CUSTOM_LENGTH 111
|
||||
# define PROV_R_INVALID_DATA 115
|
||||
# define PROV_R_INVALID_DIGEST 122
|
||||
# define PROV_R_INVALID_ITERATION_COUNT 123
|
||||
# define PROV_R_INVALID_IVLEN 116
|
||||
# define PROV_R_INVALID_IV_LENGTH 109
|
||||
# define PROV_R_INVALID_KEY 158
|
||||
# define PROV_R_INVALID_KEYLEN 117
|
||||
# define PROV_R_INVALID_KEY_LEN 124
|
||||
# define PROV_R_INVALID_KEY_LENGTH 105
|
||||
@@ -77,6 +82,8 @@ int ERR_load_PROV_strings(void);
|
||||
# define PROV_R_INVALID_TAG 110
|
||||
# define PROV_R_INVALID_TAGLEN 118
|
||||
# define PROV_R_MISSING_CEK_ALG 144
|
||||
# define PROV_R_MISSING_CIPHER 155
|
||||
# define PROV_R_MISSING_CONSTANT 156
|
||||
# define PROV_R_MISSING_KEY 128
|
||||
# define PROV_R_MISSING_MAC 150
|
||||
# define PROV_R_MISSING_MESSAGE_DIGEST 129
|
||||
@@ -91,6 +98,7 @@ int ERR_load_PROV_strings(void);
|
||||
# define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113
|
||||
# define PROV_R_NO_KEY_SET 114
|
||||
# define PROV_R_OUTPUT_BUFFER_TOO_SMALL 106
|
||||
# define PROV_R_READ_KEY 159
|
||||
# define PROV_R_TAG_NOTSET 119
|
||||
# define PROV_R_TAG_NOT_NEEDED 120
|
||||
# define PROV_R_UNABLE_TO_LOAD_SHA1 143
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -19,10 +19,14 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_DECRYPT), "bad decrypt"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_ENCODING), "bad encoding"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_LENGTH), "bad length"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_TLS_CLIENT_VERSION),
|
||||
"bad tls client version"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BN_ERROR), "bn error"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BOTH_MODE_AND_MODE_INT),
|
||||
"both mode and mode int"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_CIPHER_OPERATION_FAILED),
|
||||
"cipher operation failed"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_DECRYPT), "failed to decrypt"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GENERATE_KEY),
|
||||
"failed to generate key"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GET_PARAMETER),
|
||||
@@ -32,6 +36,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INAVLID_UKM_LENGTH),
|
||||
"inavlid ukm length"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AAD), "invalid aad"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONSTANT_LENGTH),
|
||||
"invalid constant length"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CUSTOM_LENGTH),
|
||||
"invalid custom length"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DATA), "invalid data"},
|
||||
@@ -40,6 +46,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
|
||||
"invalid iteration count"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_IVLEN), "invalid ivlen"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_IV_LENGTH), "invalid iv length"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY), "invalid key"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEYLEN), "invalid keylen"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LEN), "invalid key len"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LENGTH),
|
||||
@@ -54,6 +61,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG), "invalid tag"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAGLEN), "invalid taglen"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CEK_ALG), "missing cek alg"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CIPHER), "missing cipher"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONSTANT), "missing constant"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_KEY), "missing key"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MAC), "missing mac"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MESSAGE_DIGEST),
|
||||
@@ -72,6 +81,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_KEY_SET), "no key set"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OUTPUT_BUFFER_TOO_SMALL),
|
||||
"output buffer too small"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_READ_KEY), "read key"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOTSET), "tag notset"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_NEEDED), "tag not needed"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOAD_SHA1),
|
||||
|
||||
@@ -237,3 +237,17 @@ int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
|
||||
*macctx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ossl_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in,
|
||||
OSSL_ALGORITHM *out)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (out[0].algorithm_names == NULL) {
|
||||
for (i = j = 0; in[i].alg.algorithm_names != NULL; ++i) {
|
||||
if (in[i].capable == NULL || in[i].capable())
|
||||
out[j++] = in[i].alg;
|
||||
}
|
||||
out[j++] = in[i].alg;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user