diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-01-24 05:09:33 +0100 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-01-24 05:09:33 +0100 |
commit | dc8de3e6f1eed18617dc42d41dec6c6566c2ac0c (patch) | |
tree | 5cf78a6ef780836f16831f2776c0dc155047d742 /crypto/ffc | |
parent | Update man3/verify documentation, error text (diff) | |
download | openssl-dc8de3e6f1eed18617dc42d41dec6c6566c2ac0c.tar.xz openssl-dc8de3e6f1eed18617dc42d41dec6c6566c2ac0c.zip |
Modify DSA and DH keys to use a shared FFC_PARAMS struct
This is required in order to share code for FIPS related parameter generation and validation routinues.
Note the 'counter' field is now stored as a integer (as that is the form required for generation/validation functions).
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10860)
Diffstat (limited to 'crypto/ffc')
-rw-r--r-- | crypto/ffc/build.info | 6 | ||||
-rw-r--r-- | crypto/ffc/ffc_params.c | 191 |
2 files changed, 197 insertions, 0 deletions
diff --git a/crypto/ffc/build.info b/crypto/ffc/build.info new file mode 100644 index 0000000000..154d3c2510 --- /dev/null +++ b/crypto/ffc/build.info @@ -0,0 +1,6 @@ +LIBS=../../libcrypto + +$COMMON=ffc_params.c + +SOURCE[../../libcrypto]=$COMMON +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c new file mode 100644 index 0000000000..838ace3827 --- /dev/null +++ b/crypto/ffc/ffc_params.c @@ -0,0 +1,191 @@ +/* + * Copyright 2019-2020 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 <string.h> /* memset */ +#include "internal/ffc.h" +#ifndef FIPS_MODE +# include <openssl/asn1.h> /* ffc_params_print */ +#endif + +void ffc_params_init(FFC_PARAMS *params) +{ + memset(params, 0, sizeof(FFC_PARAMS)); + params->pcounter = -1; +} + +void ffc_params_cleanup(FFC_PARAMS *params) +{ + BN_free(params->p); + BN_free(params->q); + BN_free(params->g); + BN_free(params->j); + OPENSSL_free(params->seed); + ffc_params_init(params); +} + +void ffc_params_set0_pqg(FFC_PARAMS *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if (p != NULL && p != d->p) { + BN_free(d->p); + d->p = p; + } + if (q != NULL && q != d->q) { + BN_free(d->q); + d->q = q; + } + if (g != NULL && g != d->g) { + BN_free(d->g); + d->g = g; + } +} + +void ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, + const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = d->p; + if (q != NULL) + *q = d->q; + if (g != NULL) + *g = d->g; +} + + +/* j is the 'cofactor' that is optionally output for ASN1. */ +void ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j) +{ + BN_free(d->j); + d->j = NULL; + if (j != NULL) + d->j = j; +} + +int ffc_params_set_validate_params(FFC_PARAMS *params, + const unsigned char *seed, size_t seedlen, + int counter) +{ + if (params == NULL) + return 0; + + if (params->seed != NULL) + OPENSSL_free(params->seed); + + if (seed != NULL && seedlen > 0) { + params->seed = OPENSSL_memdup(seed, seedlen); + if (params->seed == NULL) + return 0; + params->seedlen = seedlen; + } else { + params->seed = NULL; + params->seedlen = 0; + } + params->pcounter = counter; + return 1; +} + +void ffc_params_get_validate_params(const FFC_PARAMS *params, + unsigned char **seed, size_t *seedlen, + int *pcounter) +{ + if (seed != NULL) + *seed = params->seed; + if (seedlen != NULL) + *seedlen = params->seedlen; + if (pcounter != NULL) + *pcounter = params->pcounter; +} + +static int ffc_bn_cpy(BIGNUM **dst, const BIGNUM *src) +{ + BIGNUM *a; + + /* + * If source is read only just copy the pointer, so + * we don't have to reallocate it. + */ + if (src == NULL) + a = NULL; + else if (BN_get_flags(src, BN_FLG_STATIC_DATA) + && !BN_get_flags(src, BN_FLG_MALLOCED)) + a = (BIGNUM *)src; + else if ((a = BN_dup(src)) == NULL) + return 0; + BN_clear_free(*dst); + *dst = a; + return 1; +} + +int ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src) +{ + if (!ffc_bn_cpy(&dst->p, src->p) + || !ffc_bn_cpy(&dst->g, src->g) + || !ffc_bn_cpy(&dst->q, src->q) + || !ffc_bn_cpy(&dst->j, src->j)) + return 0; + + OPENSSL_free(dst->seed); + dst->seedlen = src->seedlen; + if (src->seed != NULL) { + dst->seed = OPENSSL_memdup(src->seed, src->seedlen); + if (dst->seed == NULL) + return 0; + } else { + dst->seed = NULL; + } + dst->pcounter = src->pcounter; + return 1; +} + +int ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q) +{ + return BN_cmp(a->p, b->p) == 0 + && BN_cmp(a->g, b->g) == 0 + && (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */ +} + +#ifndef FIPS_MODE +int ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent) +{ + if (!ASN1_bn_print(bp, "prime P:", ffc->p, NULL, indent)) + goto err; + if (!ASN1_bn_print(bp, "generator G:", ffc->g, NULL, indent)) + goto err; + if (ffc->q != NULL + && !ASN1_bn_print(bp, "subgroup order Q:", ffc->q, NULL, indent)) + goto err; + if (ffc->j != NULL + && !ASN1_bn_print(bp, "subgroup factor:", ffc->j, NULL, indent)) + goto err; + if (ffc->seed != NULL) { + size_t i; + BIO_indent(bp, indent, 128); + BIO_puts(bp, "seed:"); + for (i = 0; i < ffc->seedlen; i++) { + if ((i % 15) == 0) { + if (BIO_puts(bp, "\n") <= 0 + || !BIO_indent(bp, indent + 4, 128)) + goto err; + } + if (BIO_printf(bp, "%02x%s", ffc->seed[i], + ((i + 1) == ffc->seedlen) ? "" : ":") <= 0) + goto err; + } + if (BIO_write(bp, "\n", 1) <= 0) + return 0; + } + if (ffc->pcounter != -1) { + BIO_indent(bp, indent, 128); + if (BIO_printf(bp, "counter: %d\n", ffc->pcounter) <= 0) + goto err; + } + return 1; +err: + return 0; +} +#endif /* FIPS_MODE */ |