From 2c8c02279ae6604816152f4595d8ac31395940ef Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Nov 23 2016 08:59:17 +0000 Subject: new upstream version 1.7.3 --- diff --git a/.gitignore b/.gitignore index e9b7aac..cb05f79 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.6.4-hobbled.tar.xz /libgcrypt-1.6.5-hobbled.tar.xz /libgcrypt-1.6.6-hobbled.tar.xz +/libgcrypt-1.7.3-hobbled.tar.xz diff --git a/curves.c b/curves.c index fccd1d4..f27346d 100644 --- a/curves.c +++ b/curves.c @@ -29,7 +29,7 @@ #include "../src/gcrypt-int.h" /* Number of curves defined in ../cipger/ecc.c */ -#define N_CURVES 4 +#define N_CURVES 7 /* A real world sample public key. */ static char const sample_key_1[] = @@ -41,6 +41,7 @@ static char const sample_key_1[] = " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n" +" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n" " (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE" "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n" " ))"; diff --git a/ecc-curves.c b/ecc-curves.c index ef8ff94..a971e0a 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -40,9 +40,13 @@ static const struct const char *other; /* Other name. */ } curve_aliases[] = { - /*{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1" },*/ + { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, + { "NIST P-224", "secp224r1" }, + { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */ + { "NIST P-224", "nistp224" }, /* rfc5656. */ + { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */ { "NIST P-256", "prime256v1" }, { "NIST P-256", "secp256r1" }, @@ -56,6 +60,8 @@ static const struct { "NIST P-521", "1.3.132.0.35" }, { "NIST P-521", "nistp521" }, /* rfc5656. */ + { "secp256k1", "1.3.132.0.10" }, + { NULL, NULL} }; @@ -76,9 +82,11 @@ typedef struct const char *p; /* The prime defining the field. */ const char *a, *b; /* The coefficients. For Twisted Edwards - Curves b is used for d. */ + Curves b is used for d. For Montgomery + Curves (a,b) has ((A-2)/4,B^-1). */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ + const char *h; /* Cofactor. */ } ecc_domain_parms_t; @@ -88,13 +96,38 @@ static const ecc_domain_parms_t domain_parms[] = { /* (-x^2 + y^2 = 1 + dx^2y^2) */ "Ed25519", 256, 0, - MPI_EC_TWISTEDEDWARDS, ECC_DIALECT_ED25519, + MPI_EC_EDWARDS, ECC_DIALECT_ED25519, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", "-0x01", "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658" + "0x6666666666666666666666666666666666666666666666666666666666666658", + "0x08" + }, + { + /* (y^2 = x^3 + 486662*x^2 + x) */ + "Curve25519", 256, 0, + MPI_EC_MONTGOMERY, ECC_DIALECT_STANDARD, + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", + "0x01DB41", + "0x01", + "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + "0x0000000000000000000000000000000000000000000000000000000000000009", + "0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9", + "0x08" + }, + { + "NIST P-224", 224, 1, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xffffffffffffffffffffffffffffffff000000000000000000000001", + "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe", + "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", + "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , + + "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", + "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", + "0x01" }, { "NIST P-256", 256, 1, @@ -105,7 +138,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "0x01" }, { "NIST P-384", 384, 1, @@ -122,7 +156,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f" + "0a60b1ce1d7e819d7a431d7c90ea0e5f", + "0x01" }, { "NIST P-521", 521, 1, @@ -139,10 +174,23 @@ static const ecc_domain_parms_t domain_parms[] = "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d" "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e" - "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + "0x01" }, - { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL } + { + "secp256k1", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000007", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + "0x01" + }, + + { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } }; @@ -249,10 +297,9 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, switch (domain_parms[idx].model) { case MPI_EC_WEIERSTRASS: - case MPI_EC_TWISTEDEDWARDS: - break; + case MPI_EC_EDWARDS: case MPI_EC_MONTGOMERY: - return GPG_ERR_NOT_SUPPORTED; + break; default: return GPG_ERR_BUG; } @@ -268,11 +315,21 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, if (!curve->p) curve->p = scanval (domain_parms[idx].p); if (!curve->a) - curve->a = scanval (domain_parms[idx].a); + { + curve->a = scanval (domain_parms[idx].a); + if (curve->a->sign) + mpi_add (curve->a, curve->p, curve->a); + } if (!curve->b) - curve->b = scanval (domain_parms[idx].b); + { + curve->b = scanval (domain_parms[idx].b); + if (curve->b->sign) + mpi_add (curve->b, curve->p, curve->b); + } if (!curve->n) curve->n = scanval (domain_parms[idx].n); + if (!curve->h) + curve->h = scanval (domain_parms[idx].h); if (!curve->G.x) curve->G.x = scanval (domain_parms[idx].g_x); if (!curve->G.y) @@ -288,7 +345,7 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, /* Give the name of the curve NAME, store the curve parameters into P, - A, B, G, and N if they point to NULL value. Note that G is returned + A, B, G, N, and H if they point to NULL value. Note that G is returned in standard uncompressed format. Also update MODEL and DIALECT if they are not NULL. */ gpg_err_code_t @@ -296,7 +353,7 @@ _gcry_ecc_update_curve_param (const char *name, enum gcry_mpi_ec_models *model, enum ecc_dialects *dialect, gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, - gcry_mpi_t *g, gcry_mpi_t *n) + gcry_mpi_t *g, gcry_mpi_t *n, gcry_mpi_t *h) { int idx; @@ -346,6 +403,11 @@ _gcry_ecc_update_curve_param (const char *name, _gcry_mpi_release (*n); *n = scanval (domain_parms[idx].n); } + if (h) + { + _gcry_mpi_release (*h); + *h = scanval (domain_parms[idx].h); + } return 0; } @@ -383,8 +445,8 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) /* * Extract the curve parameters.. */ - rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgn", - &E.p, &E.a, &E.b, &mpi_g, &E.n, + rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgnh", + &E.p, &E.a, &E.b, &mpi_g, &E.n, &E.h, NULL)); if (rc == GPG_ERR_NO_OBJ) { @@ -442,17 +504,22 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) if (!mpi_cmp (tmp, E.n)) { mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_x); - if (!mpi_cmp (tmp, E.G.x)) + tmp = scanval (domain_parms[idx].h); + if (!mpi_cmp (tmp, E.h)) { mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_y); - if (!mpi_cmp (tmp, E.G.y)) + tmp = scanval (domain_parms[idx].g_x); + if (!mpi_cmp (tmp, E.G.x)) { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - goto leave; + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_y); + if (!mpi_cmp (tmp, E.G.y)) + { + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + goto leave; + } } } } @@ -469,6 +536,7 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) _gcry_mpi_release (mpi_g); _gcry_mpi_point_free_parts (&E.G); _gcry_mpi_release (E.n); + _gcry_mpi_release (E.h); return result; } @@ -600,6 +668,7 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, gcry_mpi_t b = NULL; gcry_mpi_point_t G = NULL; gcry_mpi_t n = NULL; + gcry_mpi_t h = NULL; gcry_mpi_point_t Q = NULL; gcry_mpi_t d = NULL; int flags = 0; @@ -642,6 +711,9 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, errc = mpi_from_keyparam (&n, keyparam, "n"); if (errc) goto leave; + errc = mpi_from_keyparam (&h, keyparam, "h"); + if (errc) + goto leave; } } else @@ -715,6 +787,11 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, n = E->n; E->n = NULL; } + if (!h) + { + h = E->h; + E->h = NULL; + } _gcry_ecc_curve_free (E); xfree (E); } @@ -741,6 +818,11 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, ec->n = n; n = NULL; } + if (h) + { + ec->h = h; + h = NULL; + } /* Now that we know the curve name we can look for the public key Q. point_from_keyparam needs to know the curve parameters so @@ -779,6 +861,7 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, mpi_free (b); _gcry_mpi_point_release (G); mpi_free (n); + mpi_free (h); _gcry_mpi_point_release (Q); mpi_free (d); return errc; @@ -793,7 +876,7 @@ _gcry_ecc_get_param_sexp (const char *name) elliptic_curve_t E; mpi_ec_t ctx; gcry_mpi_t g_x, g_y; - gcry_mpi_t pkey[6]; + gcry_mpi_t pkey[7]; gcry_sexp_t result; int i; @@ -817,14 +900,15 @@ _gcry_ecc_get_param_sexp (const char *name) pkey[2] = E.b; pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p); pkey[4] = E.n; - pkey[5] = NULL; + pkey[5] = E.h; + pkey[6] = NULL; mpi_free (g_x); mpi_free (g_y); if (sexp_build (&result, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4])) + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)))", + pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], pkey[5])) result = NULL; for (i=0; pkey[i]; i++) @@ -851,6 +935,8 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); if (!strcmp (name, "n") && ec->n) return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); + if (!strcmp (name, "h") && ec->h) + return mpi_is_const (ec->h) && !copy? ec->h : mpi_copy (ec->h); if (!strcmp (name, "d") && ec->d) return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); @@ -884,7 +970,7 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) if (name[1] != '@') return _gcry_mpi_ec_ec2os (ec->Q, ec); - if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_TWISTEDEDWARDS) + if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_EDWARDS) { unsigned char *encpk; unsigned int encpklen; @@ -949,6 +1035,11 @@ _gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) mpi_free (ec->n); ec->n = mpi_copy (newvalue); } + else if (!strcmp (name, "h")) + { + mpi_free (ec->h); + ec->h = mpi_copy (newvalue); + } else if (*name == 'q' && (!name[1] || name[1] == '@')) { if (newvalue) diff --git a/ecc-gost.c b/ecc-gost.c new file mode 100644 index 0000000..75a2a93 --- /dev/null +++ b/ecc-gost.c @@ -0,0 +1,56 @@ +/* ecc-gots.c - Elliptic Curve GOST signatures + * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. + * Copyright (C) 2013 Dmitry Eremin-Solenikov + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include +#include +#include +#include +#include + +#include "g10lib.h" +#include "mpi.h" +#include "cipher.h" +#include "context.h" +#include "ec-context.h" +#include "ecc-common.h" +#include "pubkey-internal.h" + + +/* Compute an GOST R 34.10-01/-12 signature. + * Return the signature struct (r,s) from the message hash. The caller + * must have allocated R and S. + */ +gpg_err_code_t +_gcry_ecc_gost_sign (gcry_mpi_t input, ECC_secret_key *skey, + gcry_mpi_t r, gcry_mpi_t s) +{ + return GPG_ERR_UNSUPPORTED_ALGORITHM; +} + + +/* Verify a GOST R 34.10-01/-12 signature. + * Check if R and S verifies INPUT. + */ +gpg_err_code_t +_gcry_ecc_gost_verify (gcry_mpi_t input, ECC_public_key *pkey, + gcry_mpi_t r, gcry_mpi_t s) +{ + return GPG_ERR_UNSUPPORTED_ALGORITHM; +} diff --git a/hobble-libgcrypt b/hobble-libgcrypt index cc53cc1..81bda0f 100755 --- a/hobble-libgcrypt +++ b/hobble-libgcrypt @@ -7,5 +7,6 @@ set -e -x # EC: ????????? ??/??/2015 rm -f cipher/ecc-curves.c +rm -f cipher/ecc-gost.c rm -f tests/curves.c rm -f tests/t-mpi-point.c diff --git a/libgcrypt-1.6.1-ecc-test-fix.patch b/libgcrypt-1.6.1-ecc-test-fix.patch deleted file mode 100644 index 7e12c1b..0000000 --- a/libgcrypt-1.6.1-ecc-test-fix.patch +++ /dev/null @@ -1,214 +0,0 @@ -diff -up libgcrypt-1.6.1/tests/benchmark.c.eccfix libgcrypt-1.6.1/tests/benchmark.c ---- libgcrypt-1.6.1/tests/benchmark.c.eccfix 2014-01-27 14:36:43.000000000 +0100 -+++ libgcrypt-1.6.1/tests/benchmark.c 2014-02-28 16:14:13.042505538 +0100 -@@ -1087,8 +1087,7 @@ ecc_bench (int iterations, int print_hea - { - #if USE_ECC - gpg_error_t err; -- const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", -- "gost256", "gost512" }; -+ const char *p_sizes[] = { "256", "384", "521", "Ed25519" }; - int testno; - - if (print_header) -diff -up libgcrypt-1.6.1/tests/dsa-rfc6979.c.eccfix libgcrypt-1.6.1/tests/dsa-rfc6979.c ---- libgcrypt-1.6.1/tests/dsa-rfc6979.c.eccfix 2013-12-16 18:44:32.000000000 +0100 -+++ libgcrypt-1.6.1/tests/dsa-rfc6979.c 2014-02-28 16:18:44.138771523 +0100 -@@ -210,27 +210,6 @@ check_dsa_rfc6979 (void) - " ))" - }, - { -- "ECDSA, 192 bits (prime field)", -- "(private-key" -- " (ecdsa" -- " (curve \"NIST P-192\")" -- " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" -- " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" -- " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" -- " ))" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "(private-key" -- " (ecdsa" -- " (curve \"NIST P-224\")" -- " (q #04" -- " 00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C" -- " EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)" -- " (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)" -- " ))" -- }, -- { - "ECDSA, 256 bits (prime field)", - "(private-key" - " (ecdsa" -@@ -443,169 +422,6 @@ check_dsa_rfc6979 (void) - "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1" - }, - { -- "ECDSA, 192 bits (prime field)", -- "With SHA-1, message = \"sample\"", -- "sha1", "sample", -- "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", -- "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", -- "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-224, message = \"sample\"", -- "sha224", "sample", -- "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8", -- "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5", -- "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-256, message = \"sample\"", -- "sha256", "sample", -- "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", -- "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", -- "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-384, message = \"sample\"", -- "sha384", "sample", -- "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311", -- "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5", -- "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-512, message = \"sample\"", -- "sha512", "sample", -- "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", -- "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8", -- "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-1, message = \"test\"", -- "sha1", "test", -- "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", -- "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D", -- "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-224, message = \"test\"", -- "sha224", "test", -- "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE", -- "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34", -- "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-256, message = \"test\"", -- "sha256", "test", -- "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", -- "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", -- "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-384, message = \"test\"", -- "sha384", "test", -- "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693", -- "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367", -- "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-512, message = \"test\"", -- "sha512", "test", -- "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", -- "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739", -- "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290" -- }, -- -- -- -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-1, message = \"sample\"", -- "sha1", "sample", -- "7EEFADD91110D8DE6C2C470831387C50D3357F7F4D477054B8B426BC", -- "22226F9D40A96E19C4A301CE5B74B115303C0F3A4FD30FC257FB57AC", -- "66D1CDD83E3AF75605DD6E2FEFF196D30AA7ED7A2EDF7AF475403D69" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-224, message = \"sample\"", -- "sha224", "sample", -- "C1D1F2F10881088301880506805FEB4825FE09ACB6816C36991AA06D", -- "1CDFE6662DDE1E4A1EC4CDEDF6A1F5A2FB7FBD9145C12113E6ABFD3E", -- "A6694FD7718A21053F225D3F46197CA699D45006C06F871808F43EBC" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-256, message = \"sample\"", -- "sha256", "sample", -- "AD3029E0278F80643DE33917CE6908C70A8FF50A411F06E41DEDFCDC", -- "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA", -- "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-384, message = \"sample\"", -- "sha384", "sample", -- "52B40F5A9D3D13040F494E83D3906C6079F29981035C7BD51E5CAC40", -- "0B115E5E36F0F9EC81F1325A5952878D745E19D7BB3EABFABA77E953", -- "830F34CCDFE826CCFDC81EB4129772E20E122348A2BBD889A1B1AF1D" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-512, message = \"sample\"", -- "sha512", "sample", -- "9DB103FFEDEDF9CFDBA05184F925400C1653B8501BAB89CEA0FBEC14", -- "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397", -- "A4CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-1, message = \"test\"", -- "sha1", "test", -- "2519178F82C3F0E4F87ED5883A4E114E5B7A6E374043D8EFD329C253", -- "DEAA646EC2AF2EA8AD53ED66B2E2DDAA49A12EFD8356561451F3E21C", -- "95987796F6CF2062AB8135271DE56AE55366C045F6D9593F53787BD2" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-224, message = \"test\"", -- "sha224", "test", -- "DF8B38D40DCA3E077D0AC520BF56B6D565134D9B5F2EAE0D34900524", -- "C441CE8E261DED634E4CF84910E4C5D1D22C5CF3B732BB204DBEF019", -- "902F42847A63BDC5F6046ADA114953120F99442D76510150F372A3F4" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-256, message = \"test\"", -- "sha256", "test", -- "FF86F57924DA248D6E44E8154EB69F0AE2AEBAEE9931D0B5A969F904", -- "AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6", -- "178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-384, message = \"test\"", -- "sha384", "test", -- "7046742B839478C1B5BD31DB2E862AD868E1A45C863585B5F22BDC2D", -- "389B92682E399B26518A95506B52C03BC9379A9DADF3391A21FB0EA4", -- "414A718ED3249FF6DBC5B50C27F71F01F070944DA22AB1F78F559AAB" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-512, message = \"test\"", -- "sha512", "test", -- "E39C2AA4EA6BE2306C72126D40ED77BF9739BB4D6EF2BBB1DCB6169D", -- "049F050477C5ADD858CAC56208394B5A55BAEBBE887FDF765047C17C", -- "077EB13E7005929CEFA3CD0403C7CDCC077ADF4E44F3C41B2F60ECFF" -- }, -- { - "ECDSA, 256 bits (prime field)", - "With SHA-1, message = \"sample\"", - "sha1", "sample", diff --git a/libgcrypt-1.6.1-fips-cfgrandom.patch b/libgcrypt-1.6.1-fips-cfgrandom.patch deleted file mode 100644 index 8aae15f..0000000 --- a/libgcrypt-1.6.1-fips-cfgrandom.patch +++ /dev/null @@ -1,141 +0,0 @@ -diff -up libgcrypt-1.6.1/random/random-fips.c.cfgrandom libgcrypt-1.6.1/random/random-fips.c ---- libgcrypt-1.6.1/random/random-fips.c.cfgrandom 2014-02-28 16:06:20.026572478 +0100 -+++ libgcrypt-1.6.1/random/random-fips.c 2014-02-28 16:06:34.851915121 +0100 -@@ -27,10 +27,10 @@ - There are 3 random context which map to the different levels of - random quality: - -- Generator Seed and Key Kernel entropy (init/reseed) -- ------------------------------------------------------------ -- GCRY_VERY_STRONG_RANDOM /dev/random 256/128 bits -- GCRY_STRONG_RANDOM /dev/random 256/128 bits -+ Generator Seed and Key Kernel entropy (init/reseed) -+ --------------------------------------------------------------------------------------- -+ GCRY_VERY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits -+ GCRY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits - gcry_create_nonce GCRY_STRONG_RANDOM n/a - - All random generators return their data in 128 bit blocks. If the -@@ -40,8 +40,10 @@ - (SEED_TTL) output blocks; the re-seeding is disabled in test mode. - - The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are -- keyed and seeded from the /dev/random device. Thus these -- generators may block until the kernel has collected enough entropy. -+ keyed and seeded with data that is loaded from the /etc/gcrypt/rngseed -+ if the device or symlink to device exists xored with the data -+ from the /dev/urandom device. This allows the system administrator -+ to always seed the RNGs from /dev/random if it is required. - - The gcry_create_nonce generator is keyed and seeded from the - GCRY_STRONG_RANDOM generator. It may also block if the -@@ -560,9 +562,13 @@ get_entropy (size_t nbytes) - entropy_collect_buffer_len = 0; - - #if USE_RNDLINUX -+ _gcry_rndlinux_gather_random (entropy_collect_cb, 0, -+ X931_AES_KEYLEN, -+ -1); -+ entropy_collect_buffer_len = 0; - rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0, - X931_AES_KEYLEN, -- GCRY_VERY_STRONG_RANDOM); -+ GCRY_STRONG_RANDOM); - #elif USE_RNDW32 - do - { -@@ -713,7 +719,7 @@ get_random (void *buffer, size_t length, - || rng_ctx->seed_init_pid != getpid ()) - { - /* Just reinitialize the key & seed. */ -- gcry_cipher_close(rng_ctx->cipher_hd); -+ _gcry_cipher_close(rng_ctx->cipher_hd); - rng_ctx->cipher_hd = NULL; - rng_ctx->is_seeded = 0; - goto reinitialize; -diff -up libgcrypt-1.6.1/random/rndlinux.c.cfgrandom libgcrypt-1.6.1/random/rndlinux.c ---- libgcrypt-1.6.1/random/rndlinux.c.cfgrandom 2013-12-16 18:44:32.000000000 +0100 -+++ libgcrypt-1.6.1/random/rndlinux.c 2014-02-28 16:06:20.027572501 +0100 -@@ -36,7 +36,9 @@ - #include "g10lib.h" - #include "rand-internal.h" - --static int open_device (const char *name, int retry); -+#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed" -+ -+static int open_device (const char *name, int retry, int fatal); - - - static int -@@ -59,7 +61,7 @@ set_cloexec_flag (int fd) - * a fatal error but retries until it is able to reopen the device. - */ - static int --open_device (const char *name, int retry) -+open_device (const char *name, int retry, int fatal) - { - int fd; - -@@ -67,6 +69,8 @@ open_device (const char *name, int retry - _gcry_random_progress ("open_dev_random", 'X', 1, 0); - again: - fd = open (name, O_RDONLY); -+ if (fd == -1 && !fatal) -+ return fd; - if (fd == -1 && retry) - { - struct timeval tv; -@@ -111,6 +115,7 @@ _gcry_rndlinux_gather_random (void (*add - { - static int fd_urandom = -1; - static int fd_random = -1; -+ static int fd_configured = -1; - static unsigned char ever_opened; - int fd; - int n; -@@ -134,6 +139,11 @@ _gcry_rndlinux_gather_random (void (*add - close (fd_urandom); - fd_urandom = -1; - } -+ if (fd_configured != -1) -+ { -+ close (fd_configured); -+ fd_configured = -1; -+ } - return 0; - } - -@@ -153,20 +163,30 @@ _gcry_rndlinux_gather_random (void (*add - that we always require the device to be existent but want a more - graceful behaviour if the rarely needed close operation has been - used and the device needs to be re-opened later. */ -+ -+ if (level == -1) -+ { -+ if (fd_configured == -1) -+ fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0, 0 ); -+ fd = fd_configured; -+ if (fd == -1) -+ return -1; -+ } -+ - if (level >= 2) - { - if (fd_random == -1) - { -- fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1)); -+ fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1); - ever_opened |= 1; - } - fd = fd_random; - } -- else -+ else if (level != -1) - { - if (fd_urandom == -1) - { -- fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); -+ fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2), 1); - ever_opened |= 2; - } - fd = fd_urandom; diff --git a/libgcrypt-1.6.1-tests.patch b/libgcrypt-1.6.1-tests.patch deleted file mode 100644 index 0c00458..0000000 --- a/libgcrypt-1.6.1-tests.patch +++ /dev/null @@ -1,198 +0,0 @@ -diff -up libgcrypt-1.6.1/cipher/dsa.c.tests libgcrypt-1.6.1/cipher/dsa.c ---- libgcrypt-1.6.1/cipher/dsa.c.tests 2014-02-28 13:39:01.727288335 +0100 -+++ libgcrypt-1.6.1/cipher/dsa.c 2014-02-28 13:46:21.727458285 +0100 -@@ -423,22 +423,29 @@ generate_fips186 (DSA_secret_key *sk, un - initial_seed.seed = sexp_nth_data (initial_seed.sexp, 1, - &initial_seed.seedlen); - } -- -- /* Fixme: Enable 186-3 after it has been approved and after fixing -- the generation function. */ -- /* if (use_fips186_2) */ -- (void)use_fips186_2; -- ec = _gcry_generate_fips186_2_prime (nbits, qbits, -+ if (use_fips186_2) -+ ec = _gcry_generate_fips186_2_prime (nbits, qbits, - initial_seed.seed, - initial_seed.seedlen, - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen); -- /* else */ -- /* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */ -- /* &prime_q, &prime_p, */ -- /* r_counter, */ -- /* r_seed, r_seedlen, NULL); */ -+ else if (!domain->p || !domain->q) -+ ec = _gcry_generate_fips186_3_prime (nbits, qbits, -+ initial_seed.seed, -+ initial_seed.seedlen, -+ &prime_q, &prime_p, -+ r_counter, -+ r_seed, r_seedlen, NULL); -+ else -+ { -+ /* Domain parameters p and q are given; use them. */ -+ prime_p = mpi_copy (domain->p); -+ prime_q = mpi_copy (domain->q); -+ gcry_assert (mpi_get_nbits (prime_p) == nbits); -+ gcry_assert (mpi_get_nbits (prime_q) == qbits); -+ ec = 0; -+ } - sexp_release (initial_seed.sexp); - if (ec) - goto leave; -@@ -829,13 +829,12 @@ dsa_generate (const gcry_sexp_t genparms - sexp_release (l1); - sexp_release (domainsexp); - -- /* Check that all domain parameters are available. */ -- if (!domain.p || !domain.q || !domain.g) -+ /* Check that p and q domain parameters are available. */ -+ if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) - { - _gcry_mpi_release (domain.p); - _gcry_mpi_release (domain.q); - _gcry_mpi_release (domain.g); -- sexp_release (deriveparms); - return GPG_ERR_MISSING_VALUE; - } - -diff -up libgcrypt-1.6.1/cipher/primegen.c.tests libgcrypt-1.6.1/cipher/primegen.c ---- libgcrypt-1.6.1/cipher/primegen.c.tests 2014-01-29 10:48:38.000000000 +0100 -+++ libgcrypt-1.6.1/cipher/primegen.c 2014-02-28 13:49:52.291325147 +0100 -@@ -1649,7 +1649,7 @@ _gcry_generate_fips186_3_prime (unsigned - gpg_err_code_t ec; - unsigned char seed_help_buffer[256/8]; /* Used to hold a generated SEED. */ - unsigned char *seed_plus; /* Malloced buffer to hold SEED+x. */ -- unsigned char digest[256/8]; /* Helper buffer for SHA-1 digest. */ -+ unsigned char digest[256/8]; /* Helper buffer for SHA-x digest. */ - gcry_mpi_t val_2 = NULL; /* Helper for the prime test. */ - gcry_mpi_t tmpval = NULL; /* Helper variable. */ - int hashalgo; /* The id of the Approved Hash Function. */ -@@ -1739,7 +1739,7 @@ _gcry_generate_fips186_3_prime (unsigned - } - _gcry_mpi_release (prime_q); prime_q = NULL; - ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, -- value_u, sizeof value_u, NULL); -+ value_u, qbits/8, NULL); - if (ec) - goto leave; - mpi_set_highbit (prime_q, qbits-1 ); -@@ -1784,11 +1784,11 @@ _gcry_generate_fips186_3_prime (unsigned - if (seed_plus[i]) - break; - } -- _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen); -+ _gcry_md_hash_buffer (hashalgo, digest, seed_plus, seedlen); - - _gcry_mpi_release (tmpval); tmpval = NULL; - ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG, -- digest, sizeof digest, NULL); -+ digest, qbits/8, NULL); - if (ec) - goto leave; - if (value_j == value_n) -@@ -1824,11 +1824,11 @@ _gcry_generate_fips186_3_prime (unsigned - } - - /* Step 12: Save p, q, counter and seed. */ -- log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", -+ /* log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", - mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); - log_printhex ("fips186-3 seed", seed, seedlen); - log_printmpi ("fips186-3 p", prime_p); -- log_printmpi ("fips186-3 q", prime_q); -+ log_printmpi ("fips186-3 q", prime_q); */ - if (r_q) - { - *r_q = prime_q; -diff -up libgcrypt-1.6.1/cipher/rsa.c.tests libgcrypt-1.6.1/cipher/rsa.c ---- libgcrypt-1.6.1/cipher/rsa.c.tests 2014-01-29 08:49:49.000000000 +0100 -+++ libgcrypt-1.6.1/cipher/rsa.c 2014-02-28 13:39:01.727288335 +0100 -@@ -399,7 +399,7 @@ generate_x931 (RSA_secret_key *sk, unsig - - *swapped = 0; - -- if (e_value == 1) /* Alias for a secure value. */ -+ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ - e_value = 65537; - - /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ -diff -up libgcrypt-1.6.1/random/random-fips.c.tests libgcrypt-1.6.1/random/random-fips.c ---- libgcrypt-1.6.1/random/random-fips.c.tests 2014-01-29 10:48:38.000000000 +0100 -+++ libgcrypt-1.6.1/random/random-fips.c 2014-02-28 13:39:01.727288335 +0100 -@@ -692,6 +692,7 @@ get_random (void *buffer, size_t length, - - check_guards (rng_ctx); - -+ reinitialize: - /* Initialize the cipher handle and thus setup the key if needed. */ - if (!rng_ctx->cipher_hd) - { -@@ -711,13 +712,11 @@ get_random (void *buffer, size_t length, - if (rng_ctx->key_init_pid != getpid () - || rng_ctx->seed_init_pid != getpid ()) - { -- /* We are in a child of us. Because we have no way yet to do -- proper re-initialization (including self-checks etc), the -- only chance we have is to bail out. Obviusly a fork/exec -- won't harm because the exec overwrites the old image. */ -- fips_signal_error ("fork without proper re-initialization " -- "detected in RNG"); -- goto bailout; -+ /* Just reinitialize the key & seed. */ -+ gcry_cipher_close(rng_ctx->cipher_hd); -+ rng_ctx->cipher_hd = NULL; -+ rng_ctx->is_seeded = 0; -+ goto reinitialize; - } - - if (x931_aes_driver (buffer, length, rng_ctx)) -diff -up libgcrypt-1.6.1/tests/keygen.c.tests libgcrypt-1.6.1/tests/keygen.c ---- libgcrypt-1.6.1/tests/keygen.c.tests 2014-02-28 13:39:01.728288358 +0100 -+++ libgcrypt-1.6.1/tests/keygen.c 2014-02-28 13:42:18.288831563 +0100 -@@ -215,11 +215,11 @@ check_rsa_keys (void) - - - if (verbose) -- show ("creating 512 bit RSA key with e=257\n"); -+ show ("creating 1024 bit RSA key with e=257\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" -- " (nbits 3:512)\n" -+ " (nbits 4:1024)\n" - " (rsa-use-e 3:257)\n" - " ))", 0, 1); - if (rc) -@@ -233,11 +233,11 @@ check_rsa_keys (void) - gcry_sexp_release (key); - - if (verbose) -- show ("creating 512 bit RSA key with default e\n"); -+ show ("creating 1024 bit RSA key with default e\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" -- " (nbits 3:512)\n" -+ " (nbits 4:1024)\n" - " (rsa-use-e 1:0)\n" - " ))", 0, 1); - if (rc) -@@ -307,12 +307,12 @@ check_dsa_keys (void) - } - - if (verbose) -- show ("creating 1536 bit DSA key\n"); -+ show ("creating 2048 bit DSA key\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (dsa\n" -- " (nbits 4:1536)\n" -- " (qbits 3:224)\n" -+ " (nbits 4:2048)\n" -+ " (qbits 3:256)\n" - " ))", 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gpg_strerror (rc)); diff --git a/libgcrypt-1.6.1-use-poll.patch b/libgcrypt-1.6.1-use-poll.patch deleted file mode 100644 index 2fcaebf..0000000 --- a/libgcrypt-1.6.1-use-poll.patch +++ /dev/null @@ -1,71 +0,0 @@ -diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndlinux.c ---- libgcrypt-1.6.1/random/rndlinux.c.use-poll 2014-02-28 15:17:55.294433915 +0100 -+++ libgcrypt-1.6.1/random/rndlinux.c 2014-02-28 15:34:52.505945274 +0100 -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include "types.h" - #include "g10lib.h" - #include "rand-internal.h" -@@ -199,9 +200,11 @@ _gcry_rndlinux_gather_random (void (*add - return with something we will actually use 100ms. */ - while (length) - { -- fd_set rfds; -- struct timeval tv; - int rc; -+ struct pollfd pfd; -+ -+ pfd.fd = fd; -+ pfd.events = POLLIN; - - /* If we collected some bytes update the progress indicator. We - do this always and not just if the select timed out because -@@ -215,33 +218,18 @@ _gcry_rndlinux_gather_random (void (*add - any_need_entropy = 1; - } - -- /* If the system has no limit on the number of file descriptors -- and we encounter an fd which is larger than the fd_set size, -- we don't use the select at all. The select code is only used -- to emit progress messages. A better solution would be to -- fall back to poll() if available. */ --#ifdef FD_SETSIZE -- if (fd < FD_SETSIZE) --#endif -- { -- FD_ZERO(&rfds); -- FD_SET(fd, &rfds); -- tv.tv_sec = delay; -- tv.tv_usec = delay? 0 : 100000; -- if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) -- { -- any_need_entropy = 1; -- delay = 3; /* Use 3 seconds henceforth. */ -- continue; -- } -- else if( rc == -1 ) -- { -- log_error ("select() error: %s\n", strerror(errno)); -- if (!delay) -- delay = 1; /* Use 1 second if we encounter an error before -- we have ever blocked. */ -- continue; -- } -+ if ( !(rc=poll(&pfd, 1, delay)) ) -+ { -+ delay = 3000; /* Use 3 seconds henceforth. */ -+ continue; -+ } -+ else if( rc == -1 ) -+ { -+ log_error ("poll() error: %s\n", strerror(errno)); -+ if (!delay) -+ delay = 1000; /* Use 1 second if we encounter an error before -+ we have ever blocked. */ -+ continue; - } - - do diff --git a/libgcrypt-1.6.2-drbg.patch b/libgcrypt-1.6.2-drbg.patch deleted file mode 100644 index 306eb27..0000000 --- a/libgcrypt-1.6.2-drbg.patch +++ /dev/null @@ -1,2698 +0,0 @@ -diff -up libgcrypt-1.6.2/random/drbg.c.drbg libgcrypt-1.6.2/random/drbg.c ---- libgcrypt-1.6.2/random/drbg.c.drbg 2014-12-08 16:31:33.513992141 +0100 -+++ libgcrypt-1.6.2/random/drbg.c 2014-12-08 16:39:40.799012486 +0100 -@@ -0,0 +1,2335 @@ -+/* -+ * DRBG: Deterministic Random Bits Generator -+ * Based on NIST Recommended DRBG from NIST SP800-90A with the following -+ * properties: -+ * * CTR DRBG with DF with AES-128, AES-192, AES-256 cores -+ * * Hash DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores -+ * * HMAC DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores -+ * * with and without prediction resistance -+ * -+ * Copyright Stephan Mueller , 2014 -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, and the entire permission notice in its entirety, -+ * including the disclaimer of warranties. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The name of the author may not be used to endorse or promote -+ * products derived from this software without specific prior -+ * written permission. -+ * -+ * ALTERNATIVELY, this product may be distributed under the terms of -+ * LGPLv2+, in which case the provisions of the LGPL are -+ * required INSTEAD OF the above restrictions. (This clause is -+ * necessary due to a potential bad interaction between the LGPL and -+ * the restrictions contained in a BSD-style copyright.) -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF -+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ * -+ * gcry_control GCRYCTL_DRBG_REINIT -+ * ================================ -+ * This control request re-initializes the DRBG completely, i.e. the entire -+ * state of the DRBG is zeroized (with two exceptions listed in -+ * GCRYCTL_DRBG_SET_ENTROPY). -+ * -+ * The control request takes the following values which influences how the DRBG -+ * is re-initialized: -+ * * u32 flags: This variable specifies the DRBG type to be used for the -+ * next initialization. If set to 0, the previous DRBG type is -+ * used for the initialization. The DRBG type is an OR of the -+ * mandatory flags of the requested DRBG strength and DRBG -+ * cipher type. Optionally, the prediction resistance flag -+ * can be ORed into the flags variable. For example: -+ * - CTR-DRBG with AES-128 without prediction resistance: -+ * DRBG_CTRAES128 -+ * - HMAC-DRBG with SHA-512 with prediction resistance: -+ * DRBG_HMACSHA512 | DRBG_PREDICTION_RESIST -+ * * struct gcry_drbg_string *pers: personalization string to be used for -+ * initialization. -+ * The variable of flags is independent from the pers/perslen variables. If -+ * flags is set to 0 and perslen is set to 0, the current DRBG type is -+ * completely reset without using a personalization string. -+ * -+ * DRBG Usage -+ * ========== -+ * The SP 800-90A DRBG allows the user to specify a personalization string -+ * for initialization as well as an additional information string for each -+ * random number request. The following code fragments show how a caller -+ * uses the kernel crypto API to use the full functionality of the DRBG. -+ * -+ * Usage without any additional data -+ * --------------------------------- -+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); -+ * -+ * -+ * Usage with personalization string during initialization -+ * ------------------------------------------------------- -+ * struct gcry_drbg_string pers; -+ * char personalization[11] = "some-string"; -+ * -+ * gcry_drbg_string_fill(&pers, personalization, strlen(personalization)); -+ * // The reset completely re-initializes the DRBG with the provided -+ * // personalization string without changing the DRBG type -+ * ret = gcry_control(GCRYCTL_DRBG_REINIT, 0, &pers); -+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); -+ * -+ * -+ * Usage with additional information string during random number request -+ * --------------------------------------------------------------------- -+ * struct gcry_drbg_string addtl; -+ * char addtl_string[11] = "some-string"; -+ * -+ * gcry_drbg_string_fill(&addtl, addtl_string, strlen(addtl_string)); -+ * // The following call is a wrapper to gcry_randomize() and returns -+ * // the same error codes. -+ * gcry_randomize_drbg(outbuf, OUTLEN, GCRY_STRONG_RANDOM, &addtl); -+ * -+ * -+ * Usage with personalization and additional information strings -+ * ------------------------------------------------------------- -+ * Just mix both scenarios above. -+ * -+ * -+ * Switch the DRBG type to some other type -+ * --------------------------------------- -+ * // Switch to CTR DRBG AES-128 without prediction resistance -+ * ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_NOPR_CTRAES128, NULL); -+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "g10lib.h" -+#include "random.h" -+#include "rand-internal.h" -+#include "../cipher/bithelp.h" -+#include "ath.h" -+ -+/****************************************************************** -+ * Common data structures -+ ******************************************************************/ -+ -+struct gcry_drbg_state; -+ -+struct gcry_drbg_core -+{ -+ u32 flags; /* flags for the cipher */ -+ ushort statelen; /* maximum state length */ -+ ushort blocklen_bytes; /* block size of output in bytes */ -+ int backend_cipher; /* libgcrypt backend cipher */ -+}; -+ -+struct gcry_drbg_state_ops -+{ -+ gpg_err_code_t (*update) (struct gcry_drbg_state * drbg, -+ struct gcry_drbg_string * seed, int reseed); -+ gpg_err_code_t (*generate) (struct gcry_drbg_state * drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string * addtl); -+}; -+ -+/* DRBG test data */ -+struct gcry_drbg_test_data -+{ -+ struct gcry_drbg_string *testentropy; /* TEST PARAMETER: test entropy */ -+ int fail_seed_source:1; /* if set, the seed function will return an error */ -+}; -+ -+ -+struct gcry_drbg_state -+{ -+ unsigned char *V; /* internal state 10.1.1.1 1a) */ -+ unsigned char *C; /* hash: static value 10.1.1.1 1b) -+ * hmac / ctr: key */ -+ size_t reseed_ctr; /* Number of RNG requests since last reseed -- -+ * 10.1.1.1 1c) */ -+ unsigned char *scratchpad; /* some memory the DRBG can use for its -+ * operation -- allocated during init */ -+ int seeded:1; /* DRBG fully seeded? */ -+ int pr:1; /* Prediction resistance enabled? */ -+ int fips_primed:1; /* Continuous test primed? */ -+ unsigned char *prev; /* previous output value of gcry_drbg_blocklen -+ * for FIPS 140-2 continuous test */ -+ /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the -+ * process which did the initialization so that we can detect a fork. -+ * The volatile modifier is required so that the compiler does not -+ * optimize it away in case the getpid function is badly attributed. */ -+ pid_t seed_init_pid; -+ const struct gcry_drbg_state_ops *d_ops; -+ const struct gcry_drbg_core *core; -+ struct gcry_drbg_test_data *test_data; -+}; -+ -+enum gcry_drbg_prefixes -+{ -+ DRBG_PREFIX0 = 0x00, -+ DRBG_PREFIX1, -+ DRBG_PREFIX2, -+ DRBG_PREFIX3 -+}; -+ -+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -+ -+/*************************************************************** -+ * Backend cipher definitions available to DRBG -+ ***************************************************************/ -+ -+static const struct gcry_drbg_core gcry_drbg_cores[] = { -+ /* Hash DRBGs */ -+ {GCRY_DRBG_HASHSHA1, 55, 20, GCRY_MD_SHA1}, -+ {GCRY_DRBG_HASHSHA256, 55, 32, GCRY_MD_SHA256}, -+ {GCRY_DRBG_HASHSHA384, 111, 48, GCRY_MD_SHA384}, -+ {GCRY_DRBG_HASHSHA512, 111, 64, GCRY_MD_SHA512}, -+ /* HMAC DRBGs */ -+ {GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC, 20, 20, GCRY_MD_SHA1}, -+ {GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC, 32, 32, GCRY_MD_SHA256}, -+ {GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC, 48, 48, GCRY_MD_SHA384}, -+ {GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC, 64, 64, GCRY_MD_SHA512}, -+ /* block ciphers */ -+ {GCRY_DRBG_CTRAES | GCRY_DRBG_SYM128, 32, 16, GCRY_CIPHER_AES128}, -+ {GCRY_DRBG_CTRAES | GCRY_DRBG_SYM192, 40, 16, GCRY_CIPHER_AES192}, -+ {GCRY_DRBG_CTRAES | GCRY_DRBG_SYM256, 48, 16, GCRY_CIPHER_AES256}, -+}; -+ -+static gpg_err_code_t gcry_drbg_sym (struct gcry_drbg_state *drbg, -+ const unsigned char *key, -+ unsigned char *outval, -+ const struct gcry_drbg_string *buf); -+static gpg_err_code_t gcry_drbg_hmac (struct gcry_drbg_state *drbg, -+ const unsigned char *key, -+ unsigned char *outval, -+ const struct gcry_drbg_string *buf); -+ -+/****************************************************************** -+ ****************************************************************** -+ ****************************************************************** -+ * Generic DRBG code -+ ****************************************************************** -+ ****************************************************************** -+ ******************************************************************/ -+ -+/****************************************************************** -+ * Generic helper functions -+ ******************************************************************/ -+ -+#if 0 -+#define dbg(x) do { log_debug x; } while(0) -+#else -+#define dbg(x) -+#endif -+ -+static inline ushort -+gcry_drbg_statelen (struct gcry_drbg_state *drbg) -+{ -+ if (drbg && drbg->core) -+ return drbg->core->statelen; -+ return 0; -+} -+ -+static inline ushort -+gcry_drbg_blocklen (struct gcry_drbg_state *drbg) -+{ -+ if (drbg && drbg->core) -+ return drbg->core->blocklen_bytes; -+ return 0; -+} -+ -+static inline ushort -+gcry_drbg_keylen (struct gcry_drbg_state *drbg) -+{ -+ if (drbg && drbg->core) -+ return (drbg->core->statelen - drbg->core->blocklen_bytes); -+ return 0; -+} -+ -+static inline size_t -+gcry_drbg_max_request_bytes (void) -+{ -+ /* SP800-90A requires the limit 2**19 bits, but we return bytes */ -+ return (1 << 16); -+} -+ -+static inline size_t -+gcry_drbg_max_addtl (void) -+{ -+ /* SP800-90A requires 2**35 bytes additional info str / pers str */ -+#ifdef __LP64__ -+ return (1UL << 35); -+#else -+ /* -+ * SP800-90A allows smaller maximum numbers to be returned -- we -+ * return SIZE_MAX - 1 to allow the verification of the enforcement -+ * of this value in gcry_drbg_healthcheck_sanity. -+ */ -+ return (SIZE_MAX - 1); -+#endif -+} -+ -+static inline size_t -+gcry_drbg_max_requests (void) -+{ -+ /* SP800-90A requires 2**48 maximum requests before reseeding */ -+#ifdef __LP64__ -+ return (1UL << 48); -+#else -+ return SIZE_MAX; -+#endif -+} -+ -+/* -+ * Return strength of DRBG according to SP800-90A section 8.4 -+ * -+ * flags: DRBG flags reference -+ * -+ * Return: normalized strength value or 32 as a default to counter -+ * programming errors -+ */ -+static inline unsigned short -+gcry_drbg_sec_strength (u32 flags) -+{ -+ if ((flags & GCRY_DRBG_HASHSHA1) || (flags & GCRY_DRBG_SYM128)) -+ return 16; -+ else if (flags & GCRY_DRBG_SYM192) -+ return 24; -+ else if ((flags & GCRY_DRBG_SYM256) || (flags & GCRY_DRBG_HASHSHA256) || -+ (flags & GCRY_DRBG_HASHSHA384) || (flags & GCRY_DRBG_HASHSHA512)) -+ return 32; -+ else -+ return 32; -+} -+ -+/* -+ * FIPS 140-2 continuous self test -+ * The test is performed on the result of one round of the output -+ * function. Thus, the function implicitly knows the size of the -+ * buffer. -+ * -+ * @drbg DRBG handle -+ * @buf output buffer of random data to be checked -+ * -+ * return: -+ * false on error -+ * true on success -+ */ -+static gpg_err_code_t -+gcry_drbg_fips_continuous_test (struct gcry_drbg_state *drbg, -+ const unsigned char *buf) -+{ -+ gpg_err_code_t ret = 0; -+ /* skip test if we test the overall system */ -+ if (drbg->test_data) -+ return 1; -+ /* only perform test in FIPS mode */ -+ if (0 == fips_mode ()) -+ return 1; -+ if (!drbg->fips_primed) -+ { -+ /* Priming of FIPS test */ -+ memcpy (drbg->prev, buf, gcry_drbg_blocklen (drbg)); -+ drbg->fips_primed = 1; -+ /* return false due to priming, i.e. another round is needed */ -+ return 0; -+ } -+ ret = memcmp (drbg->prev, buf, gcry_drbg_blocklen (drbg)); -+ memcpy (drbg->prev, buf, gcry_drbg_blocklen (drbg)); -+ /* the test shall pass when the two compared values are not equal */ -+ if (ret == 0) -+ fips_signal_error ("duplicate block returned by DRBG"); -+ -+ return ret != 0; -+} -+ -+/* -+ * Convert an integer into a byte representation of this integer. -+ * The byte representation is big-endian -+ * -+ * @val value to be converted -+ * @buf buffer holding the converted integer -- caller must ensure that -+ * buffer size is at least 32 bit -+ */ -+static inline void -+gcry_drbg_cpu_to_be32 (u32 val, unsigned char *buf) -+{ -+ struct s -+ { -+ u32 conv; -+ }; -+ struct s *conversion = (struct s *) buf; -+ -+ conversion->conv = be_bswap32 (val); -+} -+ -+static void -+gcry_drbg_add_buf (unsigned char *dst, size_t dstlen, -+ unsigned char *add, size_t addlen) -+{ -+ /* implied: dstlen > addlen */ -+ unsigned char *dstptr, *addptr; -+ unsigned int remainder = 0; -+ size_t len = addlen; -+ -+ dstptr = dst + (dstlen - 1); -+ addptr = add + (addlen - 1); -+ while (len) -+ { -+ remainder += *dstptr + *addptr; -+ *dstptr = remainder & 0xff; -+ remainder >>= 8; -+ len--; -+ dstptr--; -+ addptr--; -+ } -+ len = dstlen - addlen; -+ while (len && remainder > 0) -+ { -+ remainder = *dstptr + 1; -+ *dstptr = remainder & 0xff; -+ remainder >>= 8; -+ len--; -+ dstptr--; -+ } -+} -+ -+/* Helper variables for read_cb(). -+ * -+ * The _gcry_rnd*_gather_random interface does not allow to provide a -+ * data pointer. Thus we need to use a global variable for -+ * communication. However, the then required locking is anyway a good -+ * idea because it does not make sense to have several readers of (say -+ * /dev/random). It is easier to serve them one after the other. */ -+static unsigned char *read_cb_buffer; /* The buffer. */ -+static size_t read_cb_size; /* Size of the buffer. */ -+static size_t read_cb_len; /* Used length. */ -+ -+/* Callback for generating seed from kernel device. */ -+static void -+gcry_drbg_read_cb (const void *buffer, size_t length, -+ enum random_origins origin) -+{ -+ const unsigned char *p = buffer; -+ -+ (void) origin; -+ gcry_assert (read_cb_buffer); -+ -+ /* Note that we need to protect against gatherers returning more -+ * than the requested bytes (e.g. rndw32). */ -+ while (length-- && read_cb_len < read_cb_size) -+ read_cb_buffer[read_cb_len++] = *p++; -+} -+ -+static inline int -+gcry_drbg_get_entropy (struct gcry_drbg_state *drbg, unsigned char *buffer, -+ size_t len) -+{ -+ int rc = 0; -+ -+ /* Perform testing as defined in 11.3.2 */ -+ if (drbg->test_data && drbg->test_data->fail_seed_source) -+ return -1; -+ -+ read_cb_buffer = buffer; -+ read_cb_size = len; -+ read_cb_len = 0; -+#if USE_RNDLINUX -+ _gcry_rndlinux_gather_random (gcry_drbg_read_cb, 0, len, -+ -1); -+ read_cb_len = 0; -+ rc = _gcry_rndlinux_gather_random (gcry_drbg_read_cb, 0, len, -+ GCRY_STRONG_RANDOM); -+#elif USE_RNDUNIX -+ rc = _gcry_rndunix_gather_random (read_cb, 0, length, -+ GCRY_VERY_STRONG_RANDOM); -+#elif USE_RNDW32 -+ do -+ { -+ rc = _gcry_rndw32_gather_random (read_cb, 0, length, -+ GCRY_VERY_STRONG_RANDOM); -+ } -+ while (rc >= 0 && read_cb_len < read_cb_size); -+#else -+ rc = -1; -+#endif -+ return rc; -+} -+ -+/****************************************************************** -+ * CTR DRBG callback functions -+ ******************************************************************/ -+ -+/* BCC function for CTR DRBG as defined in 10.4.3 */ -+static gpg_err_code_t -+gcry_drbg_ctr_bcc (struct gcry_drbg_state *drbg, -+ unsigned char *out, const unsigned char *key, -+ struct gcry_drbg_string *in) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ struct gcry_drbg_string *curr = in; -+ size_t inpos = curr->len; -+ const unsigned char *pos = curr->buf; -+ struct gcry_drbg_string data; -+ -+ gcry_drbg_string_fill (&data, out, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.4.3 step 1 */ -+ memset (out, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.4.3 step 2 / 4 */ -+ while (inpos) -+ { -+ short cnt = 0; -+ /* 10.4.3 step 4.1 */ -+ for (cnt = 0; cnt < gcry_drbg_blocklen (drbg); cnt++) -+ { -+ out[cnt] ^= *pos; -+ pos++; -+ inpos--; -+ /* the following branch implements the linked list -+ * iteration. If we are at the end of the current data -+ * set, we have to start using the next data set if -+ * available -- the inpos value always points to the -+ * current byte and will be zero if we have processed -+ * the last byte of the last linked list member */ -+ if (0 == inpos) -+ { -+ curr = curr->next; -+ if (NULL != curr) -+ { -+ pos = curr->buf; -+ inpos = curr->len; -+ } -+ else -+ { -+ inpos = 0; -+ break; -+ } -+ } -+ } -+ /* 10.4.3 step 4.2 */ -+ ret = gcry_drbg_sym (drbg, key, out, &data); -+ if (ret) -+ return ret; -+ /* 10.4.3 step 2 */ -+ } -+ return 0; -+} -+ -+ -+/* -+ * scratchpad usage: gcry_drbg_ctr_update is interlinked with gcry_drbg_ctr_df -+ * (and gcry_drbg_ctr_bcc, but this function does not need any temporary buffers), -+ * the scratchpad is used as follows: -+ * gcry_drbg_ctr_update: -+ * temp -+ * start: drbg->scratchpad -+ * length: gcry_drbg_statelen(drbg) + gcry_drbg_blocklen(drbg) -+ * note: the cipher writing into this variable works -+ * blocklen-wise. Now, when the statelen is not a multiple -+ * of blocklen, the generateion loop below "spills over" -+ * by at most blocklen. Thus, we need to give sufficient -+ * memory. -+ * df_data -+ * start: drbg->scratchpad + -+ * gcry_drbg_statelen(drbg) + -+ * gcry_drbg_blocklen(drbg) -+ * length: gcry_drbg_statelen(drbg) -+ * -+ * gcry_drbg_ctr_df: -+ * pad -+ * start: df_data + gcry_drbg_statelen(drbg) -+ * length: gcry_drbg_blocklen(drbg) -+ * iv -+ * start: pad + gcry_drbg_blocklen(drbg) -+ * length: gcry_drbg_blocklen(drbg) -+ * temp -+ * start: iv + gcry_drbg_blocklen(drbg) -+ * length: gcry_drbg_satelen(drbg) + gcry_drbg_blocklen(drbg) -+ * note: temp is the buffer that the BCC function operates -+ * on. BCC operates blockwise. gcry_drbg_statelen(drbg) -+ * is sufficient when the DRBG state length is a multiple -+ * of the block size. For AES192 (and maybe other ciphers) -+ * this is not correct and the length for temp is -+ * insufficient (yes, that also means for such ciphers, -+ * the final output of all BCC rounds are truncated). -+ * Therefore, add gcry_drbg_blocklen(drbg) to cover all -+ * possibilities. -+ */ -+ -+/* Derivation Function for CTR DRBG as defined in 10.4.2 */ -+static gpg_err_code_t -+gcry_drbg_ctr_df (struct gcry_drbg_state *drbg, unsigned char *df_data, -+ size_t bytes_to_return, struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ unsigned char L_N[8]; -+ /* S3 is input */ -+ struct gcry_drbg_string S1, S2, S4, cipherin; -+ struct gcry_drbg_string *tempstr = addtl; -+ unsigned char *pad = df_data + gcry_drbg_statelen (drbg); -+ unsigned char *iv = pad + gcry_drbg_blocklen (drbg); -+ unsigned char *temp = iv + gcry_drbg_blocklen (drbg); -+ size_t padlen = 0; -+ unsigned int templen = 0; -+ /* 10.4.2 step 7 */ -+ unsigned int i = 0; -+ /* 10.4.2 step 8 */ -+ const unsigned char *K = (unsigned char *) -+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" -+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; -+ unsigned char *X; -+ size_t generated_len = 0; -+ size_t inputlen = 0; -+ -+ memset (pad, 0, gcry_drbg_blocklen (drbg)); -+ memset (iv, 0, gcry_drbg_blocklen (drbg)); -+ memset (temp, 0, gcry_drbg_statelen (drbg)); -+ -+ /* 10.4.2 step 1 is implicit as we work byte-wise */ -+ -+ /* 10.4.2 step 2 */ -+ if ((512 / 8) < bytes_to_return) -+ return GPG_ERR_INV_ARG; -+ -+ /* 10.4.2 step 2 -- calculate the entire length of all input data */ -+ for (; NULL != tempstr; tempstr = tempstr->next) -+ inputlen += tempstr->len; -+ gcry_drbg_cpu_to_be32 (inputlen, &L_N[0]); -+ -+ /* 10.4.2 step 3 */ -+ gcry_drbg_cpu_to_be32 (bytes_to_return, &L_N[4]); -+ -+ /* 10.4.2 step 5: length is size of L_N, input_string, one byte, padding */ -+ padlen = (inputlen + sizeof (L_N) + 1) % (gcry_drbg_blocklen (drbg)); -+ /* wrap the padlen appropriately */ -+ if (padlen) -+ padlen = gcry_drbg_blocklen (drbg) - padlen; -+ /* pad / padlen contains the 0x80 byte and the following zero bytes, so -+ * add one for byte for 0x80 */ -+ padlen++; -+ pad[0] = 0x80; -+ -+ /* 10.4.2 step 4 -- first fill the linked list and then order it */ -+ gcry_drbg_string_fill (&S1, iv, gcry_drbg_blocklen (drbg)); -+ gcry_drbg_string_fill (&S2, L_N, sizeof (L_N)); -+ gcry_drbg_string_fill (&S4, pad, padlen); -+ S1.next = &S2; -+ S2.next = addtl; -+ -+ /* Splice in addtl between S2 and S4 -- we place S4 at the end of the -+ * input data chain. As this code is only triggered when addtl is not -+ * NULL, no NULL checks are necessary.*/ -+ tempstr = addtl; -+ while (tempstr->next) -+ tempstr = tempstr->next; -+ tempstr->next = &S4; -+ -+ /* 10.4.2 step 9 */ -+ while (templen < (gcry_drbg_keylen (drbg) + (gcry_drbg_blocklen (drbg)))) -+ { -+ /* 10.4.2 step 9.1 - the padding is implicit as the buffer -+ * holds zeros after allocation -- even the increment of i -+ * is irrelevant as the increment remains within length of i */ -+ gcry_drbg_cpu_to_be32 (i, iv); -+ /* 10.4.2 step 9.2 -- BCC and concatenation with temp */ -+ ret = gcry_drbg_ctr_bcc (drbg, temp + templen, K, &S1); -+ if (ret) -+ goto out; -+ /* 10.4.2 step 9.3 */ -+ i++; -+ templen += gcry_drbg_blocklen (drbg); -+ } -+ -+ /* 10.4.2 step 11 */ -+ /* implicit key len with seedlen - blocklen according to table 3 */ -+ X = temp + (gcry_drbg_keylen (drbg)); -+ gcry_drbg_string_fill (&cipherin, X, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.4.2 step 12: overwriting of outval */ -+ -+ /* 10.4.2 step 13 */ -+ while (generated_len < bytes_to_return) -+ { -+ short blocklen = 0; -+ /* 10.4.2 step 13.1 */ -+ /* the truncation of the key length is implicit as the key -+ * is only gcry_drbg_blocklen in size -- check for the implementation -+ * of the cipher function callback */ -+ ret = gcry_drbg_sym (drbg, temp, X, &cipherin); -+ if (ret) -+ goto out; -+ blocklen = (gcry_drbg_blocklen (drbg) < -+ (bytes_to_return - generated_len)) ? -+ gcry_drbg_blocklen (drbg) : (bytes_to_return - generated_len); -+ /* 10.4.2 step 13.2 and 14 */ -+ memcpy (df_data + generated_len, X, blocklen); -+ generated_len += blocklen; -+ } -+ -+ ret = 0; -+ -+out: -+ memset (iv, 0, gcry_drbg_blocklen (drbg)); -+ memset (temp, 0, gcry_drbg_statelen (drbg)); -+ memset (pad, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* -+ * update function of CTR DRBG as defined in 10.2.1.2 -+ * -+ * The reseed variable has an enhanced meaning compared to the update -+ * functions of the other DRBGs as follows: -+ * 0 => initial seed from initialization -+ * 1 => reseed via gcry_drbg_seed -+ * 2 => first invocation from gcry_drbg_ctr_update when addtl is present. In -+ * this case, the df_data scratchpad is not deleted so that it is -+ * available for another calls to prevent calling the DF function -+ * again. -+ * 3 => second invocation from gcry_drbg_ctr_update. When the update function -+ * was called with addtl, the df_data memory already contains the -+ * DFed addtl information and we do not need to call DF again. -+ */ -+static gpg_err_code_t -+gcry_drbg_ctr_update (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *addtl, int reseed) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ /* 10.2.1.2 step 1 */ -+ unsigned char *temp = drbg->scratchpad; -+ unsigned char *df_data = drbg->scratchpad + -+ gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg); -+ unsigned char *temp_p, *df_data_p; /* pointer to iterate over buffers */ -+ unsigned int len = 0; -+ struct gcry_drbg_string cipherin; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ memset (temp, 0, gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg)); -+ if (3 > reseed) -+ memset (df_data, 0, gcry_drbg_statelen (drbg)); -+ -+ /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */ -+ /* TODO use reseed variable to avoid re-doing DF operation */ -+ (void) reseed; -+ if (addtl && 0 < addtl->len) -+ { -+ ret = -+ gcry_drbg_ctr_df (drbg, df_data, gcry_drbg_statelen (drbg), addtl); -+ if (ret) -+ goto out; -+ } -+ -+ gcry_drbg_string_fill (&cipherin, drbg->V, gcry_drbg_blocklen (drbg)); -+ /* 10.2.1.3.2 step 2 and 3 -- are already covered as we memset(0) -+ * all memory during initialization */ -+ while (len < (gcry_drbg_statelen (drbg))) -+ { -+ /* 10.2.1.2 step 2.1 */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); -+ /* 10.2.1.2 step 2.2 */ -+ /* using target of temp + len: 10.2.1.2 step 2.3 and 3 */ -+ ret = gcry_drbg_sym (drbg, drbg->C, temp + len, &cipherin); -+ if (ret) -+ goto out; -+ /* 10.2.1.2 step 2.3 and 3 */ -+ len += gcry_drbg_blocklen (drbg); -+ } -+ -+ /* 10.2.1.2 step 4 */ -+ temp_p = temp; -+ df_data_p = df_data; -+ for (len = 0; len < gcry_drbg_statelen (drbg); len++) -+ { -+ *temp_p ^= *df_data_p; -+ df_data_p++; -+ temp_p++; -+ } -+ -+ /* 10.2.1.2 step 5 */ -+ memcpy (drbg->C, temp, gcry_drbg_keylen (drbg)); -+ /* 10.2.1.2 step 6 */ -+ memcpy (drbg->V, temp + gcry_drbg_keylen (drbg), gcry_drbg_blocklen (drbg)); -+ ret = 0; -+ -+out: -+ memset (temp, 0, gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg)); -+ if (2 != reseed) -+ memset (df_data, 0, gcry_drbg_statelen (drbg)); -+ return ret; -+} -+ -+/* -+ * scratchpad use: gcry_drbg_ctr_update is called independently from -+ * gcry_drbg_ctr_extract_bytes. Therefore, the scratchpad is reused -+ */ -+/* Generate function of CTR DRBG as defined in 10.2.1.5.2 */ -+static gpg_err_code_t -+gcry_drbg_ctr_generate (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int len = 0; -+ struct gcry_drbg_string data; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.2.1.5.2 step 2 */ -+ if (addtl && 0 < addtl->len) -+ { -+ addtl->next = NULL; -+ ret = gcry_drbg_ctr_update (drbg, addtl, 2); -+ if (ret) -+ return ret; -+ } -+ -+ /* 10.2.1.5.2 step 4.1 */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); -+ gcry_drbg_string_fill (&data, drbg->V, gcry_drbg_blocklen (drbg)); -+ while (len < buflen) -+ { -+ unsigned int outlen = 0; -+ /* 10.2.1.5.2 step 4.2 */ -+ ret = gcry_drbg_sym (drbg, drbg->C, drbg->scratchpad, &data); -+ if (ret) -+ goto out; -+ outlen = (gcry_drbg_blocklen (drbg) < (buflen - len)) ? -+ gcry_drbg_blocklen (drbg) : (buflen - len); -+ if (!gcry_drbg_fips_continuous_test (drbg, drbg->scratchpad)) -+ { -+ /* 10.2.1.5.2 step 6 */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); -+ continue; -+ } -+ /* 10.2.1.5.2 step 4.3 */ -+ memcpy (buf + len, drbg->scratchpad, outlen); -+ len += outlen; -+ /* 10.2.1.5.2 step 6 */ -+ if (len < buflen) -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); -+ } -+ -+ /* 10.2.1.5.2 step 6 */ -+ if (addtl) -+ addtl->next = NULL; -+ ret = gcry_drbg_ctr_update (drbg, addtl, 3); -+ -+out: -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+static struct gcry_drbg_state_ops gcry_drbg_ctr_ops = { -+ gcry_drbg_ctr_update, -+ gcry_drbg_ctr_generate, -+}; -+ -+/****************************************************************** -+ * HMAC DRBG callback functions -+ ******************************************************************/ -+ -+static gpg_err_code_t -+gcry_drbg_hmac_update (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *seed, int reseed) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ int i = 0; -+ struct gcry_drbg_string seed1, seed2, cipherin; -+ -+ if (!reseed) -+ /* 10.1.2.3 step 2 already implicitly covered with -+ * the initial memset(0) of drbg->C */ -+ memset (drbg->V, 1, gcry_drbg_statelen (drbg)); -+ -+ /* build linked list which implements the concatenation and fill -+ * first part*/ -+ gcry_drbg_string_fill (&seed1, drbg->V, gcry_drbg_statelen (drbg)); -+ /* buffer will be filled in for loop below with one byte */ -+ gcry_drbg_string_fill (&seed2, NULL, 1); -+ seed1.next = &seed2; -+ /* seed may be NULL */ -+ seed2.next = seed; -+ -+ gcry_drbg_string_fill (&cipherin, drbg->V, gcry_drbg_statelen (drbg)); -+ /* we execute two rounds of V/K massaging */ -+ for (i = 2; 0 < i; i--) -+ { -+ /* first round uses 0x0, second 0x1 */ -+ unsigned char prefix = DRBG_PREFIX0; -+ if (1 == i) -+ prefix = DRBG_PREFIX1; -+ /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */ -+ seed2.buf = &prefix; -+ ret = gcry_drbg_hmac (drbg, drbg->C, drbg->C, &seed1); -+ if (ret) -+ return ret; -+ -+ /* 10.1.2.2 step 2 and 5 -- HMAC for V */ -+ ret = gcry_drbg_hmac (drbg, drbg->C, drbg->V, &cipherin); -+ if (ret) -+ return ret; -+ -+ /* 10.1.2.2 step 3 */ -+ if (!seed || 0 == seed->len) -+ return ret; -+ } -+ return 0; -+} -+ -+/* generate function of HMAC DRBG as defined in 10.1.2.5 */ -+static gpg_err_code_t -+gcry_drbg_hmac_generate (struct gcry_drbg_state *drbg, -+ unsigned char *buf, -+ unsigned int buflen, struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int len = 0; -+ struct gcry_drbg_string data; -+ -+ /* 10.1.2.5 step 2 */ -+ if (addtl && 0 < addtl->len) -+ { -+ addtl->next = NULL; -+ ret = gcry_drbg_hmac_update (drbg, addtl, 1); -+ if (ret) -+ return ret; -+ } -+ -+ gcry_drbg_string_fill (&data, drbg->V, gcry_drbg_statelen (drbg)); -+ while (len < buflen) -+ { -+ unsigned int outlen = 0; -+ /* 10.1.2.5 step 4.1 */ -+ ret = gcry_drbg_hmac (drbg, drbg->C, drbg->V, &data); -+ if (ret) -+ return ret; -+ outlen = (gcry_drbg_blocklen (drbg) < (buflen - len)) ? -+ gcry_drbg_blocklen (drbg) : (buflen - len); -+ if (!gcry_drbg_fips_continuous_test (drbg, drbg->V)) -+ continue; -+ -+ /* 10.1.2.5 step 4.2 */ -+ memcpy (buf + len, drbg->V, outlen); -+ len += outlen; -+ } -+ -+ /* 10.1.2.5 step 6 */ -+ if (addtl) -+ addtl->next = NULL; -+ ret = gcry_drbg_hmac_update (drbg, addtl, 1); -+ -+ return ret; -+} -+ -+static struct gcry_drbg_state_ops gcry_drbg_hmac_ops = { -+ gcry_drbg_hmac_update, -+ gcry_drbg_hmac_generate, -+}; -+ -+/****************************************************************** -+ * Hash DRBG callback functions -+ ******************************************************************/ -+ -+/* -+ * scratchpad usage: as gcry_drbg_hash_update and gcry_drbg_hash_df are used -+ * interlinked, the scratchpad is used as follows: -+ * gcry_drbg_hash_update -+ * start: drbg->scratchpad -+ * length: gcry_drbg_statelen(drbg) -+ * gcry_drbg_hash_df: -+ * start: drbg->scratchpad + gcry_drbg_statelen(drbg) -+ * length: gcry_drbg_blocklen(drbg) -+ */ -+/* Derivation Function for Hash DRBG as defined in 10.4.1 */ -+static gpg_err_code_t -+gcry_drbg_hash_df (struct gcry_drbg_state *drbg, -+ unsigned char *outval, size_t outlen, -+ struct gcry_drbg_string *entropy) -+{ -+ gpg_err_code_t ret = 0; -+ size_t len = 0; -+ unsigned char input[5]; -+ unsigned char *tmp = drbg->scratchpad + gcry_drbg_statelen (drbg); -+ struct gcry_drbg_string data1; -+ -+ memset (tmp, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.4.1 step 3 */ -+ input[0] = 1; -+ gcry_drbg_cpu_to_be32 ((outlen * 8), &input[1]); -+ -+ /* 10.4.1 step 4.1 -- concatenation of data for input into hash */ -+ gcry_drbg_string_fill (&data1, input, 5); -+ data1.next = entropy; -+ -+ /* 10.4.1 step 4 */ -+ while (len < outlen) -+ { -+ short blocklen = 0; -+ /* 10.4.1 step 4.1 */ -+ ret = gcry_drbg_hmac (drbg, NULL, tmp, &data1); -+ if (ret) -+ goto out; -+ /* 10.4.1 step 4.2 */ -+ input[0]++; -+ blocklen = (gcry_drbg_blocklen (drbg) < (outlen - len)) ? -+ gcry_drbg_blocklen (drbg) : (outlen - len); -+ memcpy (outval + len, tmp, blocklen); -+ len += blocklen; -+ } -+ -+out: -+ memset (tmp, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */ -+static gpg_err_code_t -+gcry_drbg_hash_update (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *seed, int reseed) -+{ -+ gpg_err_code_t ret = 0; -+ struct gcry_drbg_string data1, data2; -+ unsigned char *V = drbg->scratchpad; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ memset (drbg->scratchpad, 0, gcry_drbg_statelen (drbg)); -+ if (!seed) -+ return GPG_ERR_INV_ARG; -+ -+ if (reseed) -+ { -+ /* 10.1.1.3 step 1: string length is concatenation of -+ * 1 byte, V and seed (which is concatenated entropy/addtl -+ * input) -+ */ -+ memcpy (V, drbg->V, gcry_drbg_statelen (drbg)); -+ gcry_drbg_string_fill (&data1, &prefix, 1); -+ gcry_drbg_string_fill (&data2, V, gcry_drbg_statelen (drbg)); -+ data1.next = &data2; -+ data2.next = seed; -+ } -+ else -+ { -+ gcry_drbg_string_fill (&data1, seed->buf, seed->len); -+ data1.next = seed->next; -+ } -+ -+ /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */ -+ ret = gcry_drbg_hash_df (drbg, drbg->V, gcry_drbg_statelen (drbg), &data1); -+ if (ret) -+ goto out; -+ -+ /* 10.1.1.2 / 10.1.1.3 step 4 -- concatenation */ -+ prefix = DRBG_PREFIX0; -+ gcry_drbg_string_fill (&data1, &prefix, 1); -+ gcry_drbg_string_fill (&data2, drbg->V, gcry_drbg_statelen (drbg)); -+ data1.next = &data2; -+ /* 10.1.1.2 / 10.1.1.3 step 4 -- df operation */ -+ ret = gcry_drbg_hash_df (drbg, drbg->C, gcry_drbg_statelen (drbg), &data1); -+ -+out: -+ memset (drbg->scratchpad, 0, gcry_drbg_statelen (drbg)); -+ return ret; -+} -+ -+/* processing of additional information string for Hash DRBG */ -+static gpg_err_code_t -+gcry_drbg_hash_process_addtl (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ struct gcry_drbg_string data1, data2; -+ struct gcry_drbg_string *data3; -+ unsigned char prefix = DRBG_PREFIX2; -+ -+ /* this is value w as per documentation */ -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.1.1.4 step 2 */ -+ if (!addtl || 0 == addtl->len) -+ return 0; -+ -+ /* 10.1.1.4 step 2a -- concatenation */ -+ gcry_drbg_string_fill (&data1, &prefix, 1); -+ gcry_drbg_string_fill (&data2, drbg->V, gcry_drbg_statelen (drbg)); -+ data3 = addtl; -+ data1.next = &data2; -+ data2.next = data3; -+ data3->next = NULL; -+ /* 10.1.1.4 step 2a -- cipher invocation */ -+ ret = gcry_drbg_hmac (drbg, NULL, drbg->scratchpad, &data1); -+ if (ret) -+ goto out; -+ -+ /* 10.1.1.4 step 2b */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), -+ drbg->scratchpad, gcry_drbg_blocklen (drbg)); -+ -+out: -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* -+ * Hashgen defined in 10.1.1.4 -+ */ -+static gpg_err_code_t -+gcry_drbg_hash_hashgen (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int len = 0; -+ unsigned char *src = drbg->scratchpad; -+ unsigned char *dst = drbg->scratchpad + gcry_drbg_statelen (drbg); -+ struct gcry_drbg_string data; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ /* use the scratchpad as a lookaside buffer */ -+ memset (src, 0, gcry_drbg_statelen (drbg)); -+ memset (dst, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.1.1.4 step hashgen 2 */ -+ memcpy (src, drbg->V, gcry_drbg_statelen (drbg)); -+ -+ gcry_drbg_string_fill (&data, src, gcry_drbg_statelen (drbg)); -+ while (len < buflen) -+ { -+ unsigned int outlen = 0; -+ /* 10.1.1.4 step hashgen 4.1 */ -+ ret = gcry_drbg_hmac (drbg, NULL, dst, &data); -+ if (ret) -+ goto out; -+ outlen = (gcry_drbg_blocklen (drbg) < (buflen - len)) ? -+ gcry_drbg_blocklen (drbg) : (buflen - len); -+ if (!gcry_drbg_fips_continuous_test (drbg, dst)) -+ { -+ gcry_drbg_add_buf (src, gcry_drbg_statelen (drbg), &prefix, 1); -+ continue; -+ } -+ /* 10.1.1.4 step hashgen 4.2 */ -+ memcpy (buf + len, dst, outlen); -+ len += outlen; -+ /* 10.1.1.4 hashgen step 4.3 */ -+ if (len < buflen) -+ gcry_drbg_add_buf (src, gcry_drbg_statelen (drbg), &prefix, 1); -+ } -+ -+out: -+ memset (drbg->scratchpad, 0, -+ (gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg))); -+ return ret; -+} -+ -+/* generate function for Hash DRBG as defined in 10.1.1.4 */ -+static gpg_err_code_t -+gcry_drbg_hash_generate (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned char prefix = DRBG_PREFIX3; -+ struct gcry_drbg_string data1, data2; -+ union -+ { -+ unsigned char req[8]; -+ u64 req_int; -+ } u; -+ -+ /* -+ * scratchpad usage: gcry_drbg_hash_process_addtl uses the scratchpad, but -+ * fully completes before returning. Thus, we can reuse the scratchpad -+ */ -+ /* 10.1.1.4 step 2 */ -+ ret = gcry_drbg_hash_process_addtl (drbg, addtl); -+ if (ret) -+ return ret; -+ /* 10.1.1.4 step 3 -- invocation of the Hashgen function defined in -+ * 10.1.1.4 */ -+ ret = gcry_drbg_hash_hashgen (drbg, buf, buflen); -+ if (ret) -+ return ret; -+ -+ /* this is the value H as documented in 10.1.1.4 */ -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ /* 10.1.1.4 step 4 */ -+ gcry_drbg_string_fill (&data1, &prefix, 1); -+ gcry_drbg_string_fill (&data2, drbg->V, gcry_drbg_statelen (drbg)); -+ data1.next = &data2; -+ ret = gcry_drbg_hmac (drbg, NULL, drbg->scratchpad, &data1); -+ if (ret) -+ goto out; -+ -+ /* 10.1.1.4 step 5 */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), -+ drbg->scratchpad, gcry_drbg_blocklen (drbg)); -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), drbg->C, -+ gcry_drbg_statelen (drbg)); -+ u.req_int = be_bswap64 (drbg->reseed_ctr); -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), u.req, -+ sizeof (u.req)); -+ -+out: -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* -+ * scratchpad usage: as update and generate are used isolated, both -+ * can use the scratchpad -+ */ -+static struct gcry_drbg_state_ops gcry_drbg_hash_ops = { -+ gcry_drbg_hash_update, -+ gcry_drbg_hash_generate, -+}; -+ -+/****************************************************************** -+ * Functions common for DRBG implementations -+ ******************************************************************/ -+ -+/* -+ * Seeding or reseeding of the DRBG -+ * -+ * @drbg: DRBG state struct -+ * @pers: personalization / additional information buffer -+ * @reseed: 0 for initial seed process, 1 for reseeding -+ * -+ * return: -+ * 0 on success -+ * error value otherwise -+ */ -+static gpg_err_code_t -+gcry_drbg_seed (struct gcry_drbg_state *drbg, struct gcry_drbg_string *pers, -+ int reseed) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned char *entropy = NULL; -+ size_t entropylen = 0; -+ struct gcry_drbg_string data1; -+ -+ /* 9.1 / 9.2 / 9.3.1 step 3 */ -+ if (pers && pers->len > (gcry_drbg_max_addtl ())) -+ { -+ dbg (("DRBG: personalization string too long %lu\n", pers->len)); -+ return GPG_ERR_INV_ARG; -+ } -+ if (drbg->test_data && drbg->test_data->testentropy) -+ { -+ gcry_drbg_string_fill (&data1, drbg->test_data->testentropy->buf, -+ drbg->test_data->testentropy->len); -+ dbg (("DRBG: using test entropy\n")); -+ } -+ else -+ { -+ /* Gather entropy equal to the security strength of the DRBG. -+ * With a derivation function, a nonce is required in addition -+ * to the entropy. A nonce must be at least 1/2 of the security -+ * strength of the DRBG in size. Thus, entropy * nonce is 3/2 -+ * of the strength. The consideration of a nonce is only -+ * applicable during initial seeding. */ -+ entropylen = gcry_drbg_sec_strength (drbg->core->flags); -+ if (!entropylen) -+ return GPG_ERR_GENERAL; -+ if (0 == reseed) -+ /* make sure we round up strength/2 in -+ * case it is not divisible by 2 */ -+ entropylen = ((entropylen + 1) / 2) * 3; -+ dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen)); -+ entropy = xcalloc_secure (1, entropylen); -+ if (!entropy) -+ return GPG_ERR_ENOMEM; -+ ret = gcry_drbg_get_entropy (drbg, entropy, entropylen); -+ if (ret) -+ goto out; -+ gcry_drbg_string_fill (&data1, entropy, entropylen); -+ } -+ -+ /* concatenation of entropy with personalization str / addtl input) -+ * the variable pers is directly handed by the caller, check its -+ * contents whether it is appropriate */ -+ if (pers && pers->buf && 0 < pers->len && NULL == pers->next) -+ { -+ data1.next = pers; -+ dbg (("DRBG: using personalization string\n")); -+ } -+ -+ ret = drbg->d_ops->update (drbg, &data1, reseed); -+ dbg (("DRBG: state updated with seed\n")); -+ if (ret) -+ goto out; -+ drbg->seeded = 1; -+ /* 10.1.1.2 / 10.1.1.3 step 5 */ -+ drbg->reseed_ctr = 1; -+ -+out: -+ xfree (entropy); -+ return ret; -+} -+ -+/************************************************************************* -+ * exported interfaces -+ *************************************************************************/ -+ -+/* -+ * DRBG generate function as required by SP800-90A - this function -+ * generates random numbers -+ * -+ * @drbg DRBG state handle -+ * @buf Buffer where to store the random numbers -- the buffer must already -+ * be pre-allocated by caller -+ * @buflen Length of output buffer - this value defines the number of random -+ * bytes pulled from DRBG -+ * @addtl Additional input that is mixed into state, may be NULL -- note -+ * the entropy is pulled by the DRBG internally unconditionally -+ * as defined in SP800-90A. The additional input is mixed into -+ * the state in addition to the pulled entropy. -+ * -+ * return: generated number of bytes -+ */ -+static gpg_err_code_t -+gcry_drbg_generate (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = GPG_ERR_INV_ARG; -+ -+ if (0 == buflen || !buf) -+ { -+ dbg (("DRBG: no buffer provided\n")); -+ return ret; -+ } -+ if (addtl && NULL == addtl->buf && 0 < addtl->len) -+ { -+ dbg (("DRBG: wrong format of additional information\n")); -+ return ret; -+ } -+ -+ /* 9.3.1 step 2 */ -+ if (buflen > (gcry_drbg_max_request_bytes ())) -+ { -+ dbg (("DRBG: requested random numbers too large %u\n", buflen)); -+ return ret; -+ } -+ /* 9.3.1 step 3 is implicit with the chosen DRBG */ -+ /* 9.3.1 step 4 */ -+ if (addtl && addtl->len > (gcry_drbg_max_addtl ())) -+ { -+ dbg (("DRBG: additional information string too long %lu\n", -+ addtl->len)); -+ return ret; -+ } -+ /* 9.3.1 step 5 is implicit with the chosen DRBG */ -+ /* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c -- the spec is a -+ * bit convoluted here, we make it simpler */ -+ if ((gcry_drbg_max_requests ()) < drbg->reseed_ctr) -+ drbg->seeded = 0; -+ -+ if (drbg->pr || !drbg->seeded) -+ { -+ dbg (("DRBG: reseeding before generation (prediction resistance: %s, state %s)\n", drbg->pr ? "true" : "false", drbg->seeded ? "seeded" : "unseeded")); -+ /* 9.3.1 steps 7.1 through 7.3 */ -+ ret = gcry_drbg_seed (drbg, addtl, 1); -+ if (ret) -+ return ret; -+ /* 9.3.1 step 7.4 */ -+ addtl = NULL; -+ } -+ -+ if (addtl && addtl->buf) -+ { -+ dbg (("DRBG: using additional information string\n")); -+ } -+ -+ /* 9.3.1 step 8 and 10 */ -+ ret = drbg->d_ops->generate (drbg, buf, buflen, addtl); -+ -+ /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */ -+ drbg->reseed_ctr++; -+ if (ret) -+ return ret; -+ -+ /* 11.3.3 -- re-perform self tests after some generated random -+ * numbers, the chosen value after which self test is performed -+ * is arbitrary, but it should be reasonable */ -+ /* Here we do not perform the self tests because of the following -+ * reasons: it is mathematically impossible that the initial self tests -+ * were successfully and the following are not. If the initial would -+ * pass and the following would not, the system integrity is violated. -+ * In this case, the entire system operation is questionable and it -+ * is unlikely that the integrity violation only affects to the -+ * correct operation of the DRBG. -+ */ -+#if 0 -+ if (drbg->reseed_ctr && !(drbg->reseed_ctr % 4096)) -+ { -+ dbg (("DRBG: start to perform self test\n")); -+ ret = gcry_drbg_healthcheck (); -+ if (ret) -+ { -+ log_fatal (("DRBG: self test failed\n")); -+ return ret; -+ } -+ else -+ { -+ dbg (("DRBG: self test successful\n")); -+ } -+ } -+#endif -+ -+ return ret; -+} -+ -+/* -+ * Wrapper around gcry_drbg_generate which can pull arbitrary long strings -+ * from the DRBG without hitting the maximum request limitation. -+ * -+ * Parameters: see gcry_drbg_generate -+ * Return codes: see gcry_drbg_generate -- if one gcry_drbg_generate request fails, -+ * the entire gcry_drbg_generate_long request fails -+ */ -+static gpg_err_code_t -+gcry_drbg_generate_long (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int slice = 0; -+ unsigned char *buf_p = buf; -+ unsigned len = 0; -+ do -+ { -+ unsigned int chunk = 0; -+ slice = ((buflen - len) / gcry_drbg_max_request_bytes ()); -+ chunk = slice ? gcry_drbg_max_request_bytes () : (buflen - len); -+ ret = gcry_drbg_generate (drbg, buf_p, chunk, addtl); -+ if (ret) -+ return ret; -+ buf_p += chunk; -+ len += chunk; -+ } -+ while (slice > 0 && (len < buflen)); -+ return ret; -+} -+ -+/* -+ * DRBG uninstantiate function as required by SP800-90A - this function -+ * frees all buffers and the DRBG handle -+ * -+ * @drbg DRBG state handle -+ * -+ * return -+ * 0 on success -+ */ -+static gpg_err_code_t -+gcry_drbg_uninstantiate (struct gcry_drbg_state *drbg) -+{ -+ if (!drbg) -+ return GPG_ERR_INV_ARG; -+ xfree (drbg->V); -+ drbg->V = NULL; -+ xfree (drbg->C); -+ drbg->C = NULL; -+ drbg->reseed_ctr = 0; -+ xfree (drbg->scratchpad); -+ drbg->scratchpad = NULL; -+ drbg->seeded = 0; -+ drbg->pr = 0; -+ drbg->fips_primed = 0; -+ xfree (drbg->prev); -+ drbg->prev = NULL; -+ drbg->seed_init_pid = 0; -+ return 0; -+} -+ -+/* -+ * DRBG instantiation function as required by SP800-90A - this function -+ * sets up the DRBG handle, performs the initial seeding and all sanity -+ * checks required by SP800-90A -+ * -+ * @drbg memory of state -- if NULL, new memory is allocated -+ * @pers Personalization string that is mixed into state, may be NULL -- note -+ * the entropy is pulled by the DRBG internally unconditionally -+ * as defined in SP800-90A. The additional input is mixed into -+ * the state in addition to the pulled entropy. -+ * @coreref reference to core -+ * @flags Flags defining the requested DRBG type and cipher type. The flags -+ * are defined in drbg.h and may be XORed. Beware, if you XOR multiple -+ * cipher types together, the code picks the core on a first come first -+ * serve basis as it iterates through the available cipher cores and -+ * uses the one with the first match. The minimum required flags are: -+ * cipher type flag -+ * -+ * return -+ * 0 on success -+ * error value otherwise -+ */ -+static gpg_err_code_t -+gcry_drbg_instantiate (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *pers, int coreref, int pr) -+{ -+ gpg_err_code_t ret = GPG_ERR_ENOMEM; -+ unsigned int sb_size = 0; -+ -+ if (!drbg) -+ return GPG_ERR_INV_ARG; -+ -+ dbg (("DRBG: Initializing DRBG core %d with prediction resistance %s\n", -+ coreref, pr ? "enabled" : "disabled")); -+ drbg->core = &gcry_drbg_cores[coreref]; -+ drbg->pr = pr; -+ drbg->seeded = 0; -+ if (drbg->core->flags & GCRY_DRBG_HMAC) -+ drbg->d_ops = &gcry_drbg_hmac_ops; -+ else if (drbg->core->flags & GCRY_DRBG_HASH_MASK) -+ drbg->d_ops = &gcry_drbg_hash_ops; -+ else if (drbg->core->flags & GCRY_DRBG_CTR_MASK) -+ drbg->d_ops = &gcry_drbg_ctr_ops; -+ else -+ return GPG_ERR_GENERAL; -+ /* 9.1 step 1 is implicit with the selected DRBG type -- see -+ * gcry_drbg_sec_strength() */ -+ -+ /* 9.1 step 2 is implicit as caller can select prediction resistance -+ * and the flag is copied into drbg->flags -- -+ * all DRBG types support prediction resistance */ -+ -+ /* 9.1 step 4 is implicit in gcry_drbg_sec_strength */ -+ -+ /* no allocation of drbg as this is done by the kernel crypto API */ -+ drbg->V = xcalloc_secure (1, gcry_drbg_statelen (drbg)); -+ if (!drbg->V) -+ goto err; -+ drbg->C = xcalloc_secure (1, gcry_drbg_statelen (drbg)); -+ if (!drbg->C) -+ goto err; -+ drbg->prev = xcalloc_secure (1, gcry_drbg_blocklen (drbg)); -+ if (!drbg->prev) -+ goto err; -+ drbg->fips_primed = 0; -+ /* scratchpad is only generated for CTR and Hash */ -+ if (drbg->core->flags & GCRY_DRBG_HMAC) -+ sb_size = 0; -+ else if (drbg->core->flags & GCRY_DRBG_CTR_MASK) -+ sb_size = gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg) + /* temp */ -+ gcry_drbg_statelen (drbg) + /* df_data */ -+ gcry_drbg_blocklen (drbg) + /* pad */ -+ gcry_drbg_blocklen (drbg) + /* iv */ -+ gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg); /* temp */ -+ else -+ sb_size = gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg); -+ -+ if (0 < sb_size) -+ { -+ drbg->scratchpad = xcalloc_secure (1, sb_size); -+ if (!drbg->scratchpad) -+ goto err; -+ } -+ dbg (("DRBG: state allocated with scratchpad size %u bytes\n", sb_size)); -+ -+ /* 9.1 step 6 through 11 */ -+ ret = gcry_drbg_seed (drbg, pers, 0); -+ if (ret) -+ goto err; -+ -+ dbg (("DRBG: core %d %s prediction resistance successfully initialized\n", -+ coreref, pr ? "with" : "without")); -+ return 0; -+ -+err: -+ gcry_drbg_uninstantiate (drbg); -+ return ret; -+} -+ -+/* -+ * DRBG reseed function as required by SP800-90A -+ * -+ * @drbg DRBG state handle -+ * @addtl Additional input that is mixed into state, may be NULL -- note -+ * the entropy is pulled by the DRBG internally unconditionally -+ * as defined in SP800-90A. The additional input is mixed into -+ * the state in addition to the pulled entropy. -+ * -+ * return -+ * 0 on success -+ * error value otherwise -+ */ -+static gpg_err_code_t -+gcry_drbg_reseed (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ ret = gcry_drbg_seed (drbg, addtl, 1); -+ return ret; -+} -+ -+/****************************************************************** -+ ****************************************************************** -+ ****************************************************************** -+ * libgcrypt integration code -+ ****************************************************************** -+ ****************************************************************** -+ ******************************************************************/ -+ -+/*************************************************************** -+ * libgcrypt backend functions to the RNG API code -+ ***************************************************************/ -+ -+/* global state variable holding the current instance of the DRBG -- the -+ * default DRBG type is defined in _gcry_gcry_drbg_init */ -+static struct gcry_drbg_state *gcry_drbg = NULL; -+ -+/* This is the lock we use to serialize access to this RNG. */ -+static ath_mutex_t drbg_lock; -+ -+static inline void -+gcry_drbg_lock (void) -+{ -+ int my_errno; -+ -+ my_errno = ath_mutex_lock (&drbg_lock); -+ if (my_errno) -+ log_fatal ("failed to acquire the RNG lock: %s\n", strerror (my_errno)); -+} -+ -+static inline void -+gcry_drbg_unlock (void) -+{ -+ int my_errno; -+ -+ my_errno = ath_mutex_unlock (&drbg_lock); -+ if (my_errno) -+ log_fatal ("failed to release the RNG lock: %s\n", strerror (my_errno)); -+} -+ -+/* Basic initialization is required to initialize mutexes and -+ do a few checks on the implementation. */ -+static void -+basic_initialization (void) -+{ -+ static int initialized; -+ int my_errno; -+ -+ if (initialized) -+ return; -+ initialized = 1; -+ -+ my_errno = ath_mutex_init (&drbg_lock); -+ if (my_errno) -+ log_fatal ("failed to create the RNG lock: %s\n", strerror (my_errno)); -+} -+ -+/****** helper functions where lock must be held by caller *****/ -+ -+/* Check whether given flags are known to point to an applicable DRBG */ -+static gpg_err_code_t -+gcry_drbg_algo_available (u32 flags, int *coreref) -+{ -+ int i = 0; -+ for (i = 0; ARRAY_SIZE (gcry_drbg_cores) > i; i++) -+ { -+ if ((gcry_drbg_cores[i].flags & GCRY_DRBG_CIPHER_MASK) == -+ (flags & GCRY_DRBG_CIPHER_MASK)) -+ { -+ *coreref = i; -+ return 0; -+ } -+ } -+ return GPG_ERR_GENERAL; -+} -+ -+static gpg_err_code_t -+_gcry_drbg_init_internal (u32 flags, struct gcry_drbg_string *pers) -+{ -+ gpg_err_code_t ret = 0; -+ static u32 oldflags = 0; -+ int coreref = 0; -+ int pr = 0; -+ -+ /* If a caller provides 0 as flags, use the flags of the previous -+ * initialization, otherwise use the current flags and remember them -+ * for the next invocation -+ */ -+ if (0 == flags) -+ flags = oldflags; -+ else -+ oldflags = flags; -+ -+ ret = gcry_drbg_algo_available (flags, &coreref); -+ if (ret) -+ return ret; -+ -+ if (NULL != gcry_drbg) -+ { -+ gcry_drbg_uninstantiate (gcry_drbg); -+ } -+ else -+ { -+ gcry_drbg = xcalloc_secure (1, sizeof (struct gcry_drbg_state)); -+ if (!gcry_drbg) -+ return GPG_ERR_ENOMEM; -+ } -+ if (flags & GCRY_DRBG_PREDICTION_RESIST) -+ pr = 1; -+ ret = gcry_drbg_instantiate (gcry_drbg, pers, coreref, pr); -+ if (ret) -+ fips_signal_error ("DRBG cannot be initialized"); -+ else -+ gcry_drbg->seed_init_pid = getpid (); -+ return ret; -+} -+ -+/************* calls available to common RNG code **************/ -+ -+/* -+ * Initialize one DRBG invoked by the libgcrypt API -+ */ -+void -+_gcry_drbg_init (int full) -+{ -+ (void) full; /* ignore for now */ -+ /* default DRBG */ -+ u32 flags = GCRY_DRBG_NOPR_HMACSHA256; -+ basic_initialization (); -+ gcry_drbg_lock (); -+ _gcry_drbg_init_internal (flags, NULL); -+ gcry_drbg_unlock (); -+} -+ -+/* -+ * Backend handler function for GCRYCTL_DRBG_REINIT -+ * -+ * Select a different DRBG type and initialize it. -+ * Function checks whether requested DRBG type exists and returns an error in -+ * case it does not. In case of an error, the previous instantiated DRBG is -+ * left untouched and alive. Thus, in case of an error, a DRBG is always -+ * available, even if it is not the chosen one. -+ * -+ * Re-initialization will be performed in any case regardless whether flags -+ * or personalization string are set. -+ * -+ * If flags == 0, do not change current DRBG -+ * If personalization string is NULL or its length is 0, re-initialize without -+ * personalization string -+ */ -+gpg_err_code_t -+_gcry_drbg_reinit (u32 flags, struct gcry_drbg_string *pers) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ dbg (("DRBG: reinitialize internal DRBG state with flags %u\n", flags)); -+ gcry_drbg_lock (); -+ ret = _gcry_drbg_init_internal (flags, pers); -+ gcry_drbg_unlock (); -+ return ret; -+} -+ -+/* Try to close the FDs of the random gather module. This is -+ * currently only implemented for rndlinux. */ -+void -+_gcry_drbg_close_fds (void) -+{ -+#if USE_RNDLINUX -+ gcry_drbg_lock (); -+ _gcry_rndlinux_gather_random (NULL, 0, 0, 0); -+ gcry_drbg_unlock (); -+#endif -+} -+ -+/* Print some statistics about the RNG. */ -+void -+_gcry_drbg_dump_stats (void) -+{ -+ /* Not yet implemented. */ -+ /* Maybe dumping of reseed counter? */ -+} -+ -+/* This function returns true if no real RNG is available or the -+ * quality of the RNG has been degraded for test purposes. */ -+int -+_gcry_drbg_is_faked (void) -+{ -+ return 0; /* Faked random is not allowed. */ -+} -+ -+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY -+ * should be in the range of 0..100 to indicate the goodness of the -+ * entropy added, or -1 for goodness not known. */ -+gcry_error_t -+_gcry_drbg_add_bytes (const void *buf, size_t buflen, int quality) -+{ -+ gpg_err_code_t ret = 0; -+ struct gcry_drbg_string seed; -+ (void) quality; -+ if (NULL == gcry_drbg) -+ return GPG_ERR_GENERAL; -+ gcry_drbg_string_fill (&seed, (unsigned char *) buf, buflen); -+ gcry_drbg_lock (); -+ ret = gcry_drbg_reseed (gcry_drbg, &seed); -+ gcry_drbg_unlock (); -+ return ret; -+} -+ -+/* This function is to be used for all types of random numbers, including -+ * nonces -+ */ -+void -+_gcry_drbg_randomize (void *buffer, size_t length, -+ enum gcry_random_level level) -+{ -+ (void) level; -+ gcry_drbg_lock (); -+ if (NULL == gcry_drbg) -+ { -+ fips_signal_error ("DRBG is not initialized"); -+ goto bailout; -+ } -+ -+ /* As reseeding changes the entire state of the DRBG, including any -+ * key, either a re-init or a reseed is sufficient for a fork */ -+ if (gcry_drbg->seed_init_pid != getpid ()) -+ { -+ /* We are in a child of us. Perform a reseeding. */ -+ if (gcry_drbg_reseed (gcry_drbg, NULL)) -+ { -+ fips_signal_error ("reseeding upon fork failed"); -+ log_fatal ("severe error getting random\n"); -+ goto bailout; -+ } -+ gcry_drbg->seed_init_pid = getpid (); -+ } -+ /* potential integer overflow is covered by gcry_drbg_generate which -+ * ensures that length cannot overflow an unsigned int */ -+ if (0 < length) -+ { -+ if (!buffer) -+ goto bailout; -+ if (gcry_drbg_generate_long -+ (gcry_drbg, buffer, (unsigned int) length, NULL)) -+ log_fatal ("No random numbers generated\n"); -+ } -+ else -+ { -+ struct gcry_drbg_gen *data = (struct gcry_drbg_gen *) buffer; -+ /* catch NULL pointer */ -+ if (!data || !data->outbuf) -+ { -+ fips_signal_error ("No output buffer provided"); -+ goto bailout; -+ } -+ if (gcry_drbg_generate_long (gcry_drbg, data->outbuf, data->outlen, -+ data->addtl)) -+ log_fatal ("No random numbers generated\n"); -+ } -+bailout: -+ gcry_drbg_unlock (); -+ return; -+ -+} -+ -+/*************************************************************** -+ * Self-test code -+ ***************************************************************/ -+ -+/* -+ * Test vectors from -+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip -+ */ -+struct gcry_drbg_test_vector gcry_drbg_test_pr[] = { -+ { -+ .flags = (GCRY_DRBG_PR_HASHSHA256), -+ .entropy = (unsigned char *) -+ "\x5d\xf2\x14\xbc\xf6\xb5\x4e\x0b\xf0\x0d\x6f\x2d" -+ "\xe2\x01\x66\x7b\xd0\xa4\x73\xa4\x21\xdd\xb0\xc0" -+ "\x51\x79\x09\xf4\xea\xa9\x08\xfa\xa6\x67\xe0\xe1" -+ "\xd1\x88\xa8\xad\xee\x69\x74\xb3\x55\x06\x9b\xf6", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xef\x48\x06\xa2\xc2\x45\xf1\x44\xfa\x34\x2c\xeb" -+ "\x8d\x78\x3c\x09\x8f\x34\x72\x20\xf2\xe7\xfd\x13" -+ "\x76\x0a\xf6\xdc\x3c\xf5\xc0\x15", -+ .entprb = (unsigned char *) -+ "\x4b\xbe\xe5\x24\xed\x6a\x2d\x0c\xdb\x73\x5e\x09" -+ "\xf9\xad\x67\x7c\x51\x47\x8b\x6b\x30\x2a\xc6\xde" -+ "\x76\xaa\x55\x04\x8b\x0a\x72\x95", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x3b\x14\x71\x99\xa1\xda\xa0\x42\xe6\xc8\x85\x32" -+ "\x70\x20\x32\x53\x9a\xbe\xd1\x1e\x15\xef\xfb\x4c" -+ "\x25\x6e\x19\x3a\xf0\xb9\xcb\xde\xf0\x3b\xc6\x18" -+ "\x4d\x85\x5a\x9b\xf1\xe3\xc2\x23\x03\x93\x08\xdb" -+ "\xa7\x07\x4b\x33\x78\x40\x4d\xeb\x24\xf5\x6e\x81" -+ "\x4a\x1b\x6e\xa3\x94\x52\x43\xb0\xaf\x2e\x21\xf4" -+ "\x42\x46\x8e\x90\xed\x34\x21\x75\xea\xda\x67\xb6" -+ "\xe4\xf6\xff\xc6\x31\x6c\x9a\x5a\xdb\xb3\x97\x13" -+ "\x09\xd3\x20\x98\x33\x2d\x6d\xd7\xb5\x6a\xa8\xa9" -+ "\x9a\x5b\xd6\x87\x52\xa1\x89\x2b\x4b\x9c\x64\x60" -+ "\x50\x47\xa3\x63\x81\x16\xaf\x19", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\xbe\x13\xdb\x2a\xe9\xa8\xfe\x09\x97\xe1\xce\x5d" -+ "\xe8\xbb\xc0\x7c\x4f\xcb\x62\x19\x3f\x0f\xd2\xad" -+ "\xa9\xd0\x1d\x59\x02\xc4\xff\x70", -+ .addtlb = (unsigned char *) -+ "\x6f\x96\x13\xe2\xa7\xf5\x6c\xfe\xdf\x66\xe3\x31" -+ "\x63\x76\xbf\x20\x27\x06\x49\xf1\xf3\x01\x77\x41" -+ "\x9f\xeb\xe4\x38\xfe\x67\x00\xcd", -+ .addtllen = 32, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = (GCRY_DRBG_PR_HMACSHA256), -+ .entropy = (unsigned char *) -+ "\x13\x54\x96\xfc\x1b\x7d\x28\xf3\x18\xc9\xa7\x89" -+ "\xb6\xb3\xc8\x72\xac\x00\xd4\x59\x36\x25\x05\xaf" -+ "\xa5\xdb\x96\xcb\x3c\x58\x46\x87\xa5\xaa\xbf\x20" -+ "\x3b\xfe\x23\x0e\xd1\xc7\x41\x0f\x3f\xc9\xb3\x67", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xe2\xbd\xb7\x48\x08\x06\xf3\xe1\x93\x3c\xac\x79" -+ "\xa7\x2b\x11\xda\xe3\x2e\xe1\x91\xa5\x02\x19\x57" -+ "\x20\x28\xad\xf2\x60\xd7\xcd\x45", -+ .entprb = (unsigned char *) -+ "\x8b\xd4\x69\xfc\xff\x59\x95\x95\xc6\x51\xde\x71" -+ "\x68\x5f\xfc\xf9\x4a\xab\xec\x5a\xcb\xbe\xd3\x66" -+ "\x1f\xfa\x74\xd3\xac\xa6\x74\x60", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x1f\x9e\xaf\xe4\xd2\x46\xb7\x47\x41\x4c\x65\x99" -+ "\x01\xe9\x3b\xbb\x83\x0c\x0a\xb0\xc1\x3a\xe2\xb3" -+ "\x31\x4e\xeb\x93\x73\xee\x0b\x26\xc2\x63\xa5\x75" -+ "\x45\x99\xd4\x5c\x9f\xa1\xd4\x45\x87\x6b\x20\x61" -+ "\x40\xea\x78\xa5\x32\xdf\x9e\x66\x17\xaf\xb1\x88" -+ "\x9e\x2e\x23\xdd\xc1\xda\x13\x97\x88\xa5\xb6\x5e" -+ "\x90\x14\x4e\xef\x13\xab\x5c\xd9\x2c\x97\x9e\x7c" -+ "\xd7\xf8\xce\xea\x81\xf5\xcd\x71\x15\x49\x44\xce" -+ "\x83\xb6\x05\xfb\x7d\x30\xb5\x57\x2c\x31\x4f\xfc" -+ "\xfe\x80\xb6\xc0\x13\x0c\x5b\x9b\x2e\x8f\x3d\xfc" -+ "\xc2\xa3\x0c\x11\x1b\x80\x5f\xf3", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\x64\xb6\xfc\x60\xbc\x61\x76\x23\x6d\x3f\x4a\x0f" -+ "\xe1\xb4\xd5\x20\x9e\x70\xdd\x03\x53\x6d\xbf\xce" -+ "\xcd\x56\x80\xbc\xb8\x15\xc8\xaa", -+ .perslen = 32, -+ }, -+ { -+ .flags = (GCRY_DRBG_PR_CTRAES128), -+ .entropy = (unsigned char *) -+ "\x92\x89\x8f\x31\xfa\x1c\xff\x6d\x18\x2f\x26\x06" -+ "\x43\xdf\xf8\x18\xc2\xa4\xd9\x72\xc3\xb9\xb6\x97", -+ .entropylen = 24, -+ .entpra = (unsigned char *) -+ "\x20\x72\x8a\x06\xf8\x6f\x8d\xd4\x41\xe2\x72\xb7" -+ "\xc4\x2c\xe8\x10", -+ .entprb = (unsigned char *) -+ "\x3d\xb0\xf0\x94\xf3\x05\x50\x33\x17\x86\x3e\x22" -+ "\x08\xf7\xa5\x01", -+ .entprlen = 16, -+ .expected = (unsigned char *) -+ "\x5a\x35\x39\x87\x0f\x4d\x22\xa4\x09\x24\xee\x71" -+ "\xc9\x6f\xac\x72\x0a\xd6\xf0\x88\x82\xd0\x83\x28" -+ "\x73\xec\x3f\x93\xd8\xab\x45\x23\xf0\x7e\xac\x45" -+ "\x14\x5e\x93\x9f\xb1\xd6\x76\x43\x3d\xb6\xe8\x08" -+ "\x88\xf6\xda\x89\x08\x77\x42\xfe\x1a\xf4\x3f\xc4" -+ "\x23\xc5\x1f\x68", -+ .expectedlen = 64, -+ .addtla = (unsigned char *) -+ "\x1a\x40\xfa\xe3\xcc\x6c\x7c\xa0\xf8\xda\xba\x59" -+ "\x23\x6d\xad\x1d", -+ .addtlb = (unsigned char *) -+ "\x9f\x72\x76\x6c\xc7\x46\xe5\xed\x2e\x53\x20\x12" -+ "\xbc\x59\x31\x8c", -+ .addtllen = 16, -+ .pers = (unsigned char *) -+ "\xea\x65\xee\x60\x26\x4e\x7e\xb6\x0e\x82\x68\xc4" -+ "\x37\x3c\x5c\x0b", -+ .perslen = 16, -+ }, -+}; -+ -+struct gcry_drbg_test_vector gcry_drbg_test_nopr[] = { -+ { -+ .flags = GCRY_DRBG_NOPR_HASHSHA256, -+ .entropy = (unsigned char *) -+ "\x73\xd3\xfb\xa3\x94\x5f\x2b\x5f\xb9\x8f\xf6\x9c" -+ "\x8a\x93\x17\xae\x19\xc3\x4c\xc3\xd6\xca\xa3\x2d" -+ "\x16\xfc\x42\xd2\x2d\xd5\x6f\x56\xcc\x1d\x30\xff" -+ "\x9e\x06\x3e\x09\xce\x58\xe6\x9a\x35\xb3\xa6\x56", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\x71\x7b\x93\x46\x1a\x40\xaa\x35\xa4\xaa\xc5\xe7" -+ "\x6d\x5b\x5b\x8a\xa0\xdf\x39\x7d\xae\x71\x58\x5b" -+ "\x3c\x7c\xb4\xf0\x89\xfa\x4a\x8c\xa9\x5c\x54\xc0" -+ "\x40\xdf\xbc\xce\x26\x81\x34\xf8\xba\x7d\x1c\xe8" -+ "\xad\x21\xe0\x74\xcf\x48\x84\x30\x1f\xa1\xd5\x4f" -+ "\x81\x42\x2f\xf4\xdb\x0b\x23\xf8\x73\x27\xb8\x1d" -+ "\x42\xf8\x44\x58\xd8\x5b\x29\x27\x0a\xf8\x69\x59" -+ "\xb5\x78\x44\xeb\x9e\xe0\x68\x6f\x42\x9a\xb0\x5b" -+ "\xe0\x4e\xcb\x6a\xaa\xe2\xd2\xd5\x33\x25\x3e\xe0" -+ "\x6c\xc7\x6a\x07\xa5\x03\x83\x9f\xe2\x8b\xd1\x1c" -+ "\x70\xa8\x07\x59\x97\xeb\xf6\xbe", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\xf4\xd5\x98\x3d\xa8\xfc\xfa\x37\xb7\x54\x67\x73" -+ "\xc7\xc3\xdd\x47\x34\x71\x02\x5d\xc1\xa0\xd3\x10" -+ "\xc1\x8b\xbd\xf5\x66\x34\x6f\xdd", -+ .addtlb = (unsigned char *) -+ "\xf7\x9e\x6a\x56\x0e\x73\xe9\xd9\x7a\xd1\x69\xe0" -+ "\x6f\x8c\x55\x1c\x44\xd1\xce\x6f\x28\xcc\xa4\x4d" -+ "\xa8\xc0\x85\xd1\x5a\x0c\x59\x40", -+ .addtllen = 32, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = GCRY_DRBG_NOPR_HMACSHA256, -+ .entropy = (unsigned char *) -+ "\x8d\xf0\x13\xb4\xd1\x03\x52\x30\x73\x91\x7d\xdf" -+ "\x6a\x86\x97\x93\x05\x9e\x99\x43\xfc\x86\x54\x54" -+ "\x9e\x7a\xb2\x2f\x7c\x29\xf1\x22\xda\x26\x25\xaf" -+ "\x2d\xdd\x4a\xbc\xce\x3c\xf4\xfa\x46\x59\xd8\x4e", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\xb9\x1c\xba\x4c\xc8\x4f\xa2\x5d\xf8\x61\x0b\x81" -+ "\xb6\x41\x40\x27\x68\xa2\x09\x72\x34\x93\x2e\x37" -+ "\xd5\x90\xb1\x15\x4c\xbd\x23\xf9\x74\x52\xe3\x10" -+ "\xe2\x91\xc4\x51\x46\x14\x7f\x0d\xa2\xd8\x17\x61" -+ "\xfe\x90\xfb\xa6\x4f\x94\x41\x9c\x0f\x66\x2b\x28" -+ "\xc1\xed\x94\xda\x48\x7b\xb7\xe7\x3e\xec\x79\x8f" -+ "\xbc\xf9\x81\xb7\x91\xd1\xbe\x4f\x17\x7a\x89\x07" -+ "\xaa\x3c\x40\x16\x43\xa5\xb6\x2b\x87\xb8\x9d\x66" -+ "\xb3\xa6\x0e\x40\xd4\xa8\xe4\xe9\xd8\x2a\xf6\xd2" -+ "\x70\x0e\x6f\x53\x5c\xdb\x51\xf7\x5c\x32\x17\x29" -+ "\x10\x37\x41\x03\x0c\xcc\x3a\x56", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\xb5\x71\xe6\x6d\x7c\x33\x8b\xc0\x7b\x76\xad\x37" -+ "\x57\xbb\x2f\x94\x52\xbf\x7e\x07\x43\x7a\xe8\x58" -+ "\x1c\xe7\xbc\x7c\x3a\xc6\x51\xa9", -+ .perslen = 32, -+ }, -+ { -+ .flags = GCRY_DRBG_NOPR_CTRAES128, -+ .entropy = (unsigned char *) -+ "\xc0\x70\x1f\x92\x50\x75\x8f\xcd\xf2\xbe\x73\x98" -+ "\x80\xdb\x66\xeb\x14\x68\xb4\xa5\x87\x9c\x2d\xa6", -+ .entropylen = 24, -+ .expected = (unsigned char *) -+ "\x97\xc0\xc0\xe5\xa0\xcc\xf2\x4f\x33\x63\x48\x8a" -+ "\xdb\x13\x0a\x35\x89\xbf\x80\x65\x62\xee\x13\x95" -+ "\x7c\x33\xd3\x7d\xf4\x07\x77\x7a\x2b\x65\x0b\x5f" -+ "\x45\x5c\x13\xf1\x90\x77\x7f\xc5\x04\x3f\xcc\x1a" -+ "\x38\xf8\xcd\x1b\xbb\xd5\x57\xd1\x4a\x4c\x2e\x8a" -+ "\x2b\x49\x1e\x5c", -+ .expectedlen = 64, -+ .addtla = (unsigned char *) -+ "\xf9\x01\xf8\x16\x7a\x1d\xff\xde\x8e\x3c\x83\xe2" -+ "\x44\x85\xe7\xfe", -+ .addtlb = (unsigned char *) -+ "\x17\x1c\x09\x38\xc2\x38\x9f\x97\x87\x60\x55\xb4" -+ "\x82\x16\x62\x7f", -+ .addtllen = 16, -+ .pers = (unsigned char *) -+ "\x80\x08\xae\xe8\xe9\x69\x40\xc5\x08\x73\xc7\x9f" -+ "\x8e\xcf\xe0\x02", -+ .perslen = 16, -+ }, -+}; -+ -+ -+/* -+ * Tests implement the CAVS test approach as documented in -+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf -+ */ -+ -+/* -+ * CAVS test -+ * -+ * This function is not static as it is needed for as a private API -+ * call for the CAVS test tool. -+ */ -+gpg_err_code_t -+gcry_drbg_cavs_test (struct gcry_drbg_test_vector *test, unsigned char *buf) -+{ -+ gpg_err_code_t ret = 0; -+ struct gcry_drbg_state *drbg = NULL; -+ struct gcry_drbg_test_data test_data; -+ struct gcry_drbg_string addtl, pers, testentropy; -+ int coreref = 0; -+ int pr = 0; -+ -+ ret = gcry_drbg_algo_available (test->flags, &coreref); -+ if (ret) -+ goto outbuf; -+ -+ drbg = xcalloc_secure (1, sizeof (struct gcry_drbg_state)); -+ if (!drbg) -+ { -+ ret = GPG_ERR_ENOMEM; -+ goto outbuf; -+ } -+ -+ if (test->flags & GCRY_DRBG_PREDICTION_RESIST) -+ pr = 1; -+ -+ test_data.testentropy = &testentropy; -+ gcry_drbg_string_fill (&testentropy, test->entropy, test->entropylen); -+ drbg->test_data = &test_data; -+ gcry_drbg_string_fill (&pers, test->pers, test->perslen); -+ ret = gcry_drbg_instantiate (drbg, &pers, coreref, pr); -+ if (ret) -+ goto outbuf; -+ -+ gcry_drbg_string_fill (&addtl, test->addtla, test->addtllen); -+ if (test->entpra) -+ { -+ gcry_drbg_string_fill (&testentropy, test->entpra, test->entprlen); -+ drbg->test_data = &test_data; -+ } -+ gcry_drbg_generate_long (drbg, buf, test->expectedlen, &addtl); -+ -+ gcry_drbg_string_fill (&addtl, test->addtlb, test->addtllen); -+ if (test->entprb) -+ { -+ gcry_drbg_string_fill (&testentropy, test->entprb, test->entprlen); -+ drbg->test_data = &test_data; -+ } -+ gcry_drbg_generate_long (drbg, buf, test->expectedlen, &addtl); -+ gcry_drbg_uninstantiate (drbg); -+ -+outbuf: -+ xfree (drbg); -+ return ret; -+} -+ -+/* -+ * Invoke the CAVS test and perform the final check whether the -+ * calculated random value matches the expected one. -+ * -+ * This function is not static as it is needed for as a private API -+ * call for the CAVS test tool. -+ */ -+gpg_err_code_t -+gcry_drbg_healthcheck_one (struct gcry_drbg_test_vector * test) -+{ -+ gpg_err_code_t ret = GPG_ERR_ENOMEM; -+ unsigned char *buf = xcalloc_secure (1, test->expectedlen); -+ if (!buf) -+ return GPG_ERR_ENOMEM; -+ -+ ret = gcry_drbg_cavs_test (test, buf); -+ ret = memcmp (test->expected, buf, test->expectedlen); -+ -+ xfree (buf); -+ return ret; -+} -+ -+/* -+ * Tests as defined in 11.3.2 in addition to the cipher tests: testing -+ * of the error handling. -+ * -+ * Note, testing the reseed counter is not done as an automatic reseeding -+ * is performed in gcry_drbg_generate when the reseed counter is too large. -+ */ -+static gpg_err_code_t -+gcry_drbg_healthcheck_sanity (struct gcry_drbg_test_vector *test) -+{ -+ unsigned int len = 0; -+ struct gcry_drbg_state *drbg = NULL; -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ gpg_err_code_t tmpret = GPG_ERR_GENERAL; -+ struct gcry_drbg_test_data test_data; -+ struct gcry_drbg_string addtl, testentropy; -+ int coreref = 0; -+ unsigned char *buf = NULL; -+ size_t max_addtllen, max_request_bytes; -+ -+ /* only perform test in FIPS mode */ -+ if (0 == fips_mode ()) -+ return 0; -+ -+ buf = xcalloc_secure (1, test->expectedlen); -+ if (!buf) -+ return GPG_ERR_ENOMEM; -+ tmpret = gcry_drbg_algo_available (test->flags, &coreref); -+ if (tmpret) -+ goto outbuf; -+ drbg = xcalloc_secure (1, sizeof (struct gcry_drbg_state)); -+ if (!drbg) -+ goto outbuf; -+ -+ /* if the following tests fail, it is likely that there is a buffer -+ * overflow and we get a SIGSEV */ -+ ret = gcry_drbg_instantiate (drbg, NULL, coreref, 1); -+ if (ret) -+ goto outbuf; -+ max_addtllen = gcry_drbg_max_addtl (); -+ max_request_bytes = gcry_drbg_max_request_bytes (); -+ /* overflow addtllen with additonal info string */ -+ gcry_drbg_string_fill (&addtl, test->addtla, (max_addtllen + 1)); -+ len = gcry_drbg_generate (drbg, buf, test->expectedlen, &addtl); -+ if (len) -+ goto outdrbg; -+ -+ /* overflow max_bits */ -+ len = gcry_drbg_generate (drbg, buf, (max_request_bytes + 1), NULL); -+ if (len) -+ goto outdrbg; -+ gcry_drbg_uninstantiate (drbg); -+ -+ /* test failing entropy source as defined in 11.3.2 */ -+ test_data.testentropy = NULL; -+ test_data.fail_seed_source = 1; -+ drbg->test_data = &test_data; -+ tmpret = gcry_drbg_instantiate (drbg, NULL, coreref, 0); -+ if (!tmpret) -+ goto outdrbg; -+ test_data.fail_seed_source = 0; -+ -+ test_data.testentropy = &testentropy; -+ gcry_drbg_string_fill (&testentropy, test->entropy, test->entropylen); -+ /* overflow max addtllen with personalization string */ -+ tmpret = gcry_drbg_instantiate (drbg, &addtl, coreref, 0); -+ if (!tmpret) -+ goto outdrbg; -+ -+ dbg (("DRBG: Sanity tests for failure code paths successfully completed\n")); -+ ret = 0; -+ -+outdrbg: -+ gcry_drbg_uninstantiate (drbg); -+outbuf: -+ xfree (buf); -+ xfree (drbg); -+ return ret; -+} -+ -+/* -+ * DRBG Healthcheck function as required in SP800-90A -+ * -+ * return: -+ * 0 on success (all tests pass) -+ * >0 on error (return code indicate the number of failures) -+ */ -+static int -+gcry_drbg_healthcheck (void) -+{ -+ int ret = 0; -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_nopr[0]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_nopr[1]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_nopr[2]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_pr[0]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_pr[1]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_pr[2]); -+ ret += gcry_drbg_healthcheck_sanity (&gcry_drbg_test_nopr[0]); -+ return ret; -+} -+ -+/* Run the self-tests. */ -+gcry_error_t -+_gcry_drbg_selftest (selftest_report_func_t report) -+{ -+ gcry_err_code_t ec; -+ const char *errtxt = NULL; -+ gcry_drbg_lock (); -+ if (0 != gcry_drbg_healthcheck ()) -+ errtxt = "RNG output does not match known value"; -+ gcry_drbg_unlock (); -+ if (report && errtxt) -+ report ("random", 0, "KAT", errtxt); -+ ec = errtxt ? GPG_ERR_SELFTEST_FAILED : 0; -+ return gpg_error (ec); -+} -+ -+/*************************************************************** -+ * Cipher invocations requested by DRBG -+ ***************************************************************/ -+ -+static gpg_err_code_t -+gcry_drbg_hmac (struct gcry_drbg_state *drbg, const unsigned char *key, -+ unsigned char *outval, const struct gcry_drbg_string *buf) -+{ -+ gpg_error_t err; -+ gcry_md_hd_t hd; -+ -+ if (key) -+ { -+ err = -+ _gcry_md_open (&hd, drbg->core->backend_cipher, GCRY_MD_FLAG_HMAC); -+ if (err) -+ return err; -+ err = _gcry_md_setkey (hd, key, gcry_drbg_statelen (drbg)); -+ if (err) -+ return err; -+ } -+ else -+ { -+ err = _gcry_md_open (&hd, drbg->core->backend_cipher, 0); -+ if (err) -+ return err; -+ } -+ for (; NULL != buf; buf = buf->next) -+ _gcry_md_write (hd, buf->buf, buf->len); -+ _gcry_md_final (hd); -+ memcpy (outval, _gcry_md_read (hd, drbg->core->backend_cipher), -+ gcry_drbg_blocklen (drbg)); -+ _gcry_md_close (hd); -+ return 0; -+} -+ -+static gpg_err_code_t -+gcry_drbg_sym (struct gcry_drbg_state *drbg, const unsigned char *key, -+ unsigned char *outval, const struct gcry_drbg_string *buf) -+{ -+ gpg_error_t err; -+ gcry_cipher_hd_t hd; -+ -+ if (gcry_drbg_blocklen (drbg) != -+ _gcry_cipher_get_algo_blklen (drbg->core->backend_cipher)) -+ return -GPG_ERR_NO_ERROR; -+ if (gcry_drbg_blocklen (drbg) < buf->len) -+ return -GPG_ERR_NO_ERROR; -+ err = -+ _gcry_cipher_open (&hd, drbg->core->backend_cipher, GCRY_CIPHER_MODE_ECB, -+ 0); -+ if (err) -+ return err; -+ err = _gcry_cipher_setkey (hd, key, gcry_drbg_keylen (drbg)); -+ if (err) -+ { -+ _gcry_cipher_close (hd); -+ return err; -+ } -+ /* in is only component */ -+ _gcry_cipher_encrypt (hd, outval, gcry_drbg_blocklen (drbg), buf->buf, -+ buf->len); -+ _gcry_cipher_close (hd); -+ return 0; -+} -diff -up libgcrypt-1.6.2/random/Makefile.am.drbg libgcrypt-1.6.2/random/Makefile.am ---- libgcrypt-1.6.2/random/Makefile.am.drbg 2014-08-18 08:46:51.000000000 +0200 -+++ libgcrypt-1.6.2/random/Makefile.am 2014-12-08 16:31:33.513992141 +0100 -@@ -35,6 +35,7 @@ random.c random.h \ - rand-internal.h \ - random-csprng.c \ - random-fips.c \ -+drbg.c \ - random-system.c \ - rndhw.c - -diff -up libgcrypt-1.6.2/random/Makefile.in.drbg libgcrypt-1.6.2/random/Makefile.in ---- libgcrypt-1.6.2/random/Makefile.in.drbg 2014-08-21 15:14:08.000000000 +0200 -+++ libgcrypt-1.6.2/random/Makefile.in 2014-12-08 16:31:33.514992163 +0100 -@@ -92,11 +92,11 @@ CONFIG_CLEAN_VPATH_FILES = - LTLIBRARIES = $(noinst_LTLIBRARIES) - am__DEPENDENCIES_1 = - am__librandom_la_SOURCES_DIST = random.c random.h rand-internal.h \ -- random-csprng.c random-fips.c random-system.c rndhw.c \ -+ random-csprng.c random-fips.c drbg.c random-system.c rndhw.c \ - random-daemon.c - @USE_RANDOM_DAEMON_TRUE@am__objects_1 = random-daemon.lo - am_librandom_la_OBJECTS = random.lo random-csprng.lo random-fips.lo \ -- random-system.lo rndhw.lo $(am__objects_1) -+ drbg.lo random-system.lo rndhw.lo $(am__objects_1) - librandom_la_OBJECTS = $(am_librandom_la_OBJECTS) - AM_V_lt = $(am__v_lt_@AM_V@) - am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -@@ -310,7 +310,7 @@ GCRYPT_MODULES = @GCRYPT_RANDOM@ - librandom_la_DEPENDENCIES = $(GCRYPT_MODULES) - librandom_la_LIBADD = $(GCRYPT_MODULES) - librandom_la_SOURCES = random.c random.h rand-internal.h \ -- random-csprng.c random-fips.c random-system.c rndhw.c \ -+ random-csprng.c random-fips.c drbg.c random-system.c rndhw.c \ - $(am__append_1) - EXTRA_librandom_la_SOURCES = \ - rndlinux.c \ -@@ -374,6 +374,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-csprng.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-daemon.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-fips.Plo@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drbg.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-system.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndegd.Plo@am__quote@ -diff -up libgcrypt-1.6.2/random/rand-internal.h.drbg libgcrypt-1.6.2/random/rand-internal.h ---- libgcrypt-1.6.2/random/rand-internal.h.drbg 2014-08-18 08:46:51.000000000 +0200 -+++ libgcrypt-1.6.2/random/rand-internal.h 2014-12-08 16:31:33.514992163 +0100 -@@ -88,6 +88,15 @@ gcry_err_code_t _gcry_rngfips_run_extern - char *buffer, size_t buflen); - void _gcry_rngfips_deinit_external_test (void *context); - -+/* drbg-gcry.h */ -+void _gcry_drbg_init(int full); -+void _gcry_drbg_close_fds(void); -+void _gcry_drbg_dump_stats(void); -+int _gcry_drbg_is_faked (void); -+gcry_error_t _gcry_drbg_add_bytes (const void *buf, size_t buflen, int quality); -+void _gcry_drbg_randomize (void *buffer, size_t length, -+ enum gcry_random_level level); -+gcry_error_t _gcry_drbg_selftest (selftest_report_func_t report); - - /*-- random-system.c --*/ - void _gcry_rngsystem_initialize (int full); -diff -up libgcrypt-1.6.2/random/random.c.drbg libgcrypt-1.6.2/random/random.c ---- libgcrypt-1.6.2/random/random.c.drbg 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/random/random.c 2014-12-08 16:31:33.514992163 +0100 -@@ -153,11 +153,11 @@ _gcry_random_initialize (int full) - } - - if (fips_mode ()) -- _gcry_rngfips_initialize (full); -+ _gcry_drbg_init(full); - else if (rng_types.standard) - _gcry_rngcsprng_initialize (full); - else if (rng_types.fips) -- _gcry_rngfips_initialize (full); -+ _gcry_drbg_init(full); - else if (rng_types.system) - _gcry_rngsystem_initialize (full); - else -@@ -174,11 +174,11 @@ _gcry_random_close_fds (void) - the entropy gatherer. */ - - if (fips_mode ()) -- _gcry_rngfips_close_fds (); -+ _gcry_drbg_close_fds (); - else if (rng_types.standard) - _gcry_rngcsprng_close_fds (); - else if (rng_types.fips) -- _gcry_rngfips_close_fds (); -+ _gcry_drbg_close_fds (); - else if (rng_types.system) - _gcry_rngsystem_close_fds (); - else -@@ -212,7 +212,7 @@ void - _gcry_random_dump_stats (void) - { - if (fips_mode ()) -- _gcry_rngfips_dump_stats (); -+ _gcry_drbg_dump_stats (); - else - _gcry_rngcsprng_dump_stats (); - } -@@ -271,7 +271,7 @@ int - _gcry_random_is_faked (void) - { - if (fips_mode ()) -- return _gcry_rngfips_is_faked (); -+ return _gcry_drbg_is_faked (); - else - return _gcry_rngcsprng_is_faked (); - } -@@ -301,11 +301,11 @@ static void - do_randomize (void *buffer, size_t length, enum gcry_random_level level) - { - if (fips_mode ()) -- _gcry_rngfips_randomize (buffer, length, level); -+ _gcry_drbg_randomize (buffer, length, level); - else if (rng_types.standard) - _gcry_rngcsprng_randomize (buffer, length, level); - else if (rng_types.fips) -- _gcry_rngfips_randomize (buffer, length, level); -+ _gcry_drbg_randomize (buffer, length, level); - else if (rng_types.system) - _gcry_rngsystem_randomize (buffer, length, level); - else /* default */ -@@ -437,7 +437,7 @@ _gcry_create_nonce (void *buffer, size_t - nonce generator which is seeded by the RNG actual in use. */ - if (fips_mode ()) - { -- _gcry_rngfips_create_nonce (buffer, length); -+ _gcry_drbg_randomize (buffer, length, GCRY_WEAK_RANDOM); - return; - } - -@@ -514,7 +514,7 @@ gpg_error_t - _gcry_random_selftest (selftest_report_func_t report) - { - if (fips_mode ()) -- return _gcry_rngfips_selftest (report); -+ return _gcry_drbg_selftest (report); - else - return 0; /* No selftests yet. */ - } -@@ -530,6 +530,7 @@ _gcry_random_init_external_test (void ** - const void *seed, size_t seedlen, - const void *dt, size_t dtlen) - { -+ return GPG_ERR_NOT_SUPPORTED; - (void)flags; - if (fips_mode ()) - return _gcry_rngfips_init_external_test (r_context, flags, key, keylen, -@@ -544,6 +545,7 @@ _gcry_random_init_external_test (void ** - gcry_err_code_t - _gcry_random_run_external_test (void *context, char *buffer, size_t buflen) - { -+ return GPG_ERR_NOT_SUPPORTED; - if (fips_mode ()) - return _gcry_rngfips_run_external_test (context, buffer, buflen); - else -@@ -554,6 +556,7 @@ _gcry_random_run_external_test (void *co - void - _gcry_random_deinit_external_test (void *context) - { -+ return; - if (fips_mode ()) - _gcry_rngfips_deinit_external_test (context); - } -diff -up libgcrypt-1.6.2/random/random.h.drbg libgcrypt-1.6.2/random/random.h ---- libgcrypt-1.6.2/random/random.h.drbg 2014-08-18 08:46:51.000000000 +0200 -+++ libgcrypt-1.6.2/random/random.h 2014-12-08 16:31:33.514992163 +0100 -@@ -54,7 +54,29 @@ gcry_err_code_t _gcry_random_run_externa - char *buffer, size_t buflen); - void _gcry_random_deinit_external_test (void *context); - -+/*-- drbg.c --*/ -+gpg_err_code_t _gcry_drbg_reinit (u32 flags, struct gcry_drbg_string *pers); -+/* private interfaces for testing of DRBG */ -+struct gcry_drbg_test_vector -+{ -+ u32 flags; -+ unsigned char *entropy; -+ size_t entropylen; -+ unsigned char *entpra; -+ unsigned char *entprb; -+ size_t entprlen; -+ unsigned char *addtla; -+ unsigned char *addtlb; -+ size_t addtllen; -+ unsigned char *pers; -+ size_t perslen; -+ unsigned char *expected; -+ size_t expectedlen; -+}; - -+gpg_err_code_t gcry_drbg_cavs_test (struct gcry_drbg_test_vector *test, -+ unsigned char *buf); -+gpg_err_code_t gcry_drbg_healthcheck_one (struct gcry_drbg_test_vector *test); - /*-- rndegd.c --*/ - gpg_error_t _gcry_rndegd_set_socket_name (const char *name); - -diff -up libgcrypt-1.6.2/src/gcrypt.h.in.drbg libgcrypt-1.6.2/src/gcrypt.h.in ---- libgcrypt-1.6.2/src/gcrypt.h.in.drbg 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/src/gcrypt.h.in 2014-12-08 16:31:33.515992186 +0100 -@@ -329,7 +329,9 @@ enum gcry_ctl_cmds - GCRYCTL_SET_CCM_LENGTHS = 69, - GCRYCTL_CLOSE_RANDOM_DEVICE = 70, - GCRYCTL_INACTIVATE_FIPS_FLAG = 71, -- GCRYCTL_REACTIVATE_FIPS_FLAG = 72 -+ GCRYCTL_REACTIVATE_FIPS_FLAG = 72, -+ GCRYCTL_DRBG_REINIT = 74 -+ /* Note: 75 is used internally */ - }; - - /* Perform various operations defined by CMD. */ -@@ -1668,6 +1670,110 @@ int gcry_is_secure (const void *a) _GCRY - /* Return true if Libgcrypt is in FIPS mode. */ - #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) - -+/* DRBG input data structure for DRBG generate with additional information -+ * string */ -+struct gcry_drbg_gen { -+ unsigned char *outbuf; /* output buffer for random numbers */ -+ unsigned int outlen; /* size of output buffer */ -+ struct gcry_drbg_string *addtl; /* input buffer for -+ * additional information string */ -+}; -+ -+/* -+ * Concatenation Helper and string operation helper -+ * -+ * SP800-90A requires the concatenation of different data. To avoid copying -+ * buffers around or allocate additional memory, the following data structure -+ * is used to point to the original memory with its size. In addition, it -+ * is used to build a linked list. The linked list defines the concatenation -+ * of individual buffers. The order of memory block referenced in that -+ * linked list determines the order of concatenation. -+ */ -+/* DRBG string definition */ -+struct gcry_drbg_string { -+ const unsigned char *buf; -+ size_t len; -+ struct gcry_drbg_string *next; -+}; -+ -+#define gcry_drbg_string_fill(s, b, l) \ -+do { \ -+ (s)->buf = (b); \ -+ (s)->len = (l); \ -+ (s)->next = NULL; \ -+} while (0) -+ -+/* this is a wrapper function for users of libgcrypt */ -+#define gcry_randomize_drbg(ob, ol, lvl, add) \ -+do { \ -+ struct gcry_drbg_gen genbuf; \ -+ genbuf.outbuf = (unsigned char *)(ob); \ -+ genbuf.outlen = (ol); \ -+ genbuf.addtl = (add); \ -+ gcry_randomize(&genbuf, 0, (lvl)); \ -+} while (0) -+ -+/* -+ * DRBG flags bitmasks -+ * -+ * 31 (B) 28 19 (A) 0 -+ * +-+-+-+--------+---+-----------+-----+ -+ * |~|~|u|~~~~~~~~| 3 | 2 | 1 | -+ * +-+-+-+--------+- -+-----------+-----+ -+ * ctl flg| |drbg use selection flags -+ * -+ */ -+ -+/* internal state control flags (B) */ -+#define GCRY_DRBG_PREDICTION_RESIST ((u_int32_t)1<<28) -+ -+/* CTR type modifiers (A.1)*/ -+#define GCRY_DRBG_CTRAES ((u_int32_t)1<<0) -+#define GCRY_DRBG_CTRSERPENT ((u_int32_t)1<<1) -+#define GCRY_DRBG_CTRTWOFISH ((u_int32_t)1<<2) -+#define GCRY_DRBG_CTR_MASK (GCRY_DRBG_CTRAES | GCRY_DRBG_CTRSERPENT | GCRY_DRBG_CTRTWOFISH) -+ -+/* HASH type modifiers (A.2)*/ -+#define GCRY_DRBG_HASHSHA1 ((u_int32_t)1<<4) -+#define GCRY_DRBG_HASHSHA224 ((u_int32_t)1<<5) -+#define GCRY_DRBG_HASHSHA256 ((u_int32_t)1<<6) -+#define GCRY_DRBG_HASHSHA384 ((u_int32_t)1<<7) -+#define GCRY_DRBG_HASHSHA512 ((u_int32_t)1<<8) -+#define GCRY_DRBG_HASH_MASK (GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HASHSHA224 | \ -+ GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HASHSHA384 | \ -+ GCRY_DRBG_HASHSHA512) -+/* type modifiers (A.3)*/ -+#define GCRY_DRBG_HMAC ((u_int32_t)1<<12) -+#define GCRY_DRBG_SYM128 ((u_int32_t)1<<13) -+#define GCRY_DRBG_SYM192 ((u_int32_t)1<<14) -+#define GCRY_DRBG_SYM256 ((u_int32_t)1<<15) -+#define GCRY_DRBG_TYPE_MASK (GCRY_DRBG_HMAC | GCRY_DRBG_SYM128 | GCRY_DRBG_SYM192 | \ -+ GCRY_DRBG_SYM256) -+#define GCRY_DRBG_CIPHER_MASK (GCRY_DRBG_CTR_MASK | GCRY_DRBG_HASH_MASK | GCRY_DRBG_TYPE_MASK) -+ -+#define GCRY_DRBG_PR_CTRAES128 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_CTRAES | GCRY_DRBG_SYM128) -+#define GCRY_DRBG_PR_CTRAES192 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_CTRAES | GCRY_DRBG_SYM192) -+#define GCRY_DRBG_PR_CTRAES256 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_CTRAES | GCRY_DRBG_SYM256) -+#define GCRY_DRBG_NOPR_CTRAES128 (GCRY_DRBG_CTRAES | GCRY_DRBG_SYM128) -+#define GCRY_DRBG_NOPR_CTRAES192 (GCRY_DRBG_CTRAES | GCRY_DRBG_SYM192) -+#define GCRY_DRBG_NOPR_CTRAES256 (GCRY_DRBG_CTRAES | GCRY_DRBG_SYM256) -+#define GCRY_DRBG_PR_HASHSHA1 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA1) -+#define GCRY_DRBG_PR_HASHSHA256 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA256) -+#define GCRY_DRBG_PR_HASHSHA384 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA384) -+#define GCRY_DRBG_PR_HASHSHA512 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA512) -+#define GCRY_DRBG_NOPR_HASHSHA1 (GCRY_DRBG_HASHSHA1) -+#define GCRY_DRBG_NOPR_HASHSHA256 (GCRY_DRBG_HASHSHA256) -+#define GCRY_DRBG_NOPR_HASHSHA384 (GCRY_DRBG_HASHSHA384) -+#define GCRY_DRBG_NOPR_HASHSHA512 (GCRY_DRBG_HASHSHA512) -+#define GCRY_DRBG_PR_HMACSHA1 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_PR_HMACSHA256 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_PR_HMACSHA384 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_PR_HMACSHA512 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_NOPR_HMACSHA1 (GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_NOPR_HMACSHA256 (GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_NOPR_HMACSHA384 (GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_NOPR_HMACSHA512 (GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC) -+#define DRBG_NOPR_HMACSHA512 GCRY_DRBG_NOPR_HMACSHA512 /* deprecated leftover */ - - #if 0 /* (Keep Emacsens' auto-indent happy.) */ - { -diff -up libgcrypt-1.6.2/src/global.c.drbg libgcrypt-1.6.2/src/global.c ---- libgcrypt-1.6.2/src/global.c.drbg 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/src/global.c 2014-12-08 16:31:33.515992186 +0100 -@@ -680,6 +680,28 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - rc = GPG_ERR_NOT_IMPLEMENTED; - break; - -+ case GCRYCTL_DRBG_REINIT: -+ { -+ u32 flags = va_arg (arg_ptr, u32); -+ struct gcry_drbg_string *pers = va_arg (arg_ptr, -+ struct gcry_drbg_string *); -+ rc = _gcry_drbg_reinit(flags, pers); -+ } -+ break; -+ -+ case 75: -+ { -+ struct gcry_drbg_test_vector *test = -+ va_arg (arg_ptr, struct gcry_drbg_test_vector *); -+ unsigned char *buf = va_arg (arg_ptr, unsigned char *); -+ -+ if (buf) -+ rc = gcry_drbg_cavs_test (test, buf); -+ else -+ rc = gcry_drbg_healthcheck_one (test); -+ } -+ break; -+ - default: - _gcry_set_preferred_rng_type (0); - rc = GPG_ERR_INV_OP; diff --git a/libgcrypt-1.6.2-fips-cavs.patch b/libgcrypt-1.6.2-fips-cavs.patch deleted file mode 100644 index 52067b0..0000000 --- a/libgcrypt-1.6.2-fips-cavs.patch +++ /dev/null @@ -1,1400 +0,0 @@ -diff -up libgcrypt-1.5.3/tests/cavs_driver.pl.cavs libgcrypt-1.5.3/tests/cavs_driver.pl ---- libgcrypt-1.5.3/tests/cavs_driver.pl.cavs 2013-05-22 18:02:55.000000000 +0200 -+++ libgcrypt-1.5.3/tests/cavs_driver.pl 2014-10-21 09:38:34.250691408 +0200 -@@ -1,9 +1,11 @@ - #!/usr/bin/env perl - # --# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $ -+# $Id: cavs_driver.pl 2124 2010-12-20 07:56:30Z smueller $ - # - # CAVS test driver (based on the OpenSSL driver) - # Written by: Stephan Müller -+# Werner Koch (libgcrypt interface) -+# Tomas Mraz (addition of DSA2) - # Copyright (c) atsec information security corporation - # - # Permission is hereby granted, free of charge, to any person obtaining a copy -@@ -85,13 +87,16 @@ - # T[CBC|CFB??|ECB|OFB]varkey - # T[CBC|CFB??|ECB|OFB]invperm - # T[CBC|CFB??|ECB|OFB]vartext -+# WARNING: TDES in CFB and OFB mode problems see below - # - # ANSI X9.31 RNG - # ANSI931_AES128MCT - # ANSI931_AES128VST - # --# DSA -+# DSA2 - # PQGGen -+# PQGVer -+# KeyPair - # SigGen - # SigVer - # -@@ -101,6 +106,36 @@ - # RC4PltBD - # RC4REGT - # -+# -+# TDES MCT for CFB and OFB: -+# ------------------------- -+# The inner loop cannot be handled by this script. If you want to have tests -+# for these cipher types, implement your own inner loop and add it to -+# crypto_mct. -+# -+# the value $next_source in crypto_mct is NOT set by the standard implementation -+# of this script. It would need to be set as follows for these two (code take -+# from fipsdrv.c from libgcrypt - the value input at the end will contain the -+# the value for $next_source: -+# -+# ... inner loop ... -+# ... -+# get_current_iv (hd, last_iv, blocklen); -+# ... encrypt / decrypt (input is the data to be en/decrypted and output is the -+# result of operation) ... -+# if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB)) -+# memcpy (input, last_iv, blocklen); -+# else if (cipher_mode == GCRY_CIPHER_MODE_OFB) -+# memcpy (input, last_iv, blocklen); -+# else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) -+# { -+# /* Reconstruct the output vector. */ -+# int i; -+# for (i=0; i < blocklen; i++) -+# input[i] ^= output[i]; -+# } -+# ... inner loop ends ... -+# ==> now, the value of input is to be put into $next_source - - use strict; - use warnings; -@@ -226,6 +261,8 @@ my $hmac; - # Generate the P, Q, G, Seed, counter, h (value used to generate g) values - # for DSA - # $1: modulus size -+# $2: q size -+# $3: seed (might be empty string) - # return: string with the calculated values in hex format, where each value - # is separated from the previous with a \n in the following order: - # P\n -@@ -236,6 +273,19 @@ my $hmac; - # h - my $dsa_pqggen; - -+# Generate the G value from P and Q -+# for DSA -+# $1: modulus size -+# $2: q size -+# $3: P in hex form -+# $4: Q in hex form -+# return: string with the calculated values in hex format, where each value -+# is separated from the previous with a \n in the following order: -+# P\n -+# Q\n -+# G\n -+my $dsa_ggen; -+ - # - # Generate an DSA public key from the provided parameters: - # $1: Name of file to create -@@ -255,16 +305,30 @@ my $dsa_verify; - - # generate a new DSA key with the following properties: - # PEM format --# $1 keyfile name --# return: file created, hash with keys of P, Q, G in hex format -+# $1: modulus size -+# $2: q size -+# $3 keyfile name -+# return: file created with key, string with values of P, Q, G in hex format - my $gen_dsakey; - -+# generate a new DSA private key XY parameters in domain: -+# PEM format -+# $1: P in hex form -+# $2: Q in hex form -+# $3: G in hex form -+# return: string with values of X, Y in hex format -+my $gen_dsakey_domain; -+ - # Sign a message with DSA - # $1: data to be signed in hex form - # $2: Key file in PEM format with the private key - # return: hash of digest information in hex format with Y, R, S as keys - my $dsa_sign; - -+my $rsa_keygen; -+ -+my $rsa_keygen_kat; -+ - ################################################################ - ##### OpenSSL interface functions - ################################################################ -@@ -404,6 +468,35 @@ sub libgcrypt_rsa_derive($$$$$$$$) { - } - - -+sub libgcrypt_rsa_keygen($) { -+ my $n = shift; -+ my $sexp; -+ -+ $n = sprintf ("%u", $n); -+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")))\n"; -+ -+ return pipe_through_program($sexp, "fipsdrv rsa-keygen"); -+} -+ -+ -+sub libgcrypt_rsa_keygen_kat($$$$) { -+ my $n = shift; -+ my $e = shift; -+ my $p = shift; -+ my $q = shift; -+ my $sexp; -+ -+ $n = sprintf ("%u", $n); -+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" -+ . "(test-parms" -+ . "(e #$e#)" -+ . "(p #$p#)" -+ . "(q #$q#))))\n"; -+ -+ return pipe_through_program($sexp, "fipsdrv rsa-keygen-kat"); -+} -+ -+ - sub libgcrypt_rsa_sign($$$) { - my $data = shift; - my $hashalgo = shift; -@@ -500,17 +593,32 @@ sub libgcrypt_hmac($$$$) { - return pipe_through_program($msg, $program); - } - --sub libgcrypt_dsa_pqggen($) { -+sub libgcrypt_dsa_pqggen($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $seed = shift; -+ -+ my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; -+ return pipe_through_program($seed, $program); -+} -+ -+sub libgcrypt_dsa_ggen($$$$) { - my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $domain = "(domain (p #$p#)(q #$q#))"; - -- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; - return pipe_through_program("", $program); - } - --sub libgcrypt_gen_dsakey($) { -+sub libgcrypt_gen_dsakey($$$) { -+ my $mod = shift; -+ my $qsize = shift; - my $file = shift; - -- my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key $file dsa-gen"; - my $tmp; - my %ret; - -@@ -519,10 +627,21 @@ sub libgcrypt_gen_dsakey($) { - $tmp = pipe_through_program("", $program); - die "dsa key gen failed: file $file not created" if (! -f $file); - -- @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); -+ @ret{'P', 'Q', 'G'} = split(/\n/, $tmp); - return %ret; - } - -+sub libgcrypt_gen_dsakey_domain($$$) { -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $domain = "(domain (p #$p#)(q #$q#)(g #$g#))"; -+ -+ my $program = "fipsdrv --key '$domain' dsa-gen-key"; -+ -+ return pipe_through_program("", $program); -+} -+ - sub libgcrypt_dsa_genpubkey($$$$$) { - my $filename = shift; - my $p = shift; -@@ -1139,7 +1258,7 @@ sub hmac_kat($$$$) { - $out .= "Tlen = $tlen\n"; - $out .= "Key = $key\n"; - $out .= "Msg = $msg\n"; -- $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; -+ $out .= "Mac = " . lc(&$hmac($key, $tlen, $msg, $hashtype{$tlen})) . "\n"; - - return $out; - } -@@ -1205,7 +1324,7 @@ sub crypto_mct($$$$$$$$) { - } - my ($CO, $CI); - my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); -- $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/); -+ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/ && defined($state_cipher_des)); - my $pid = open2($CO, $CI, $cipher_imp); - - my $calc_data = $iv; # CT[j] -@@ -1213,8 +1332,8 @@ sub crypto_mct($$$$$$$$) { - my $old_old_calc_data; # CT[j-2] - my $next_source; - -- # TDES inner loop implements logic within driver -- if ($cipher =~ /des/) { -+ # TDES inner loop implements logic within driver of libgcrypt -+ if ($cipher =~ /des/ && $opt{'I'} && $opt{'I'} eq 'libgcrypt' ) { - # Need to provide a dummy IV in case of ECB mode. - my $iv_arg = (defined($iv) && $iv ne "") - ? bin2hex($iv) -@@ -1238,6 +1357,10 @@ sub crypto_mct($$$$$$$$) { - $line = <$CO>; - } else { - for (my $j = 0; $j < $iloop; ++$j) { -+ if ($cipher =~ /des-ede3-ofb/ || -+ (!$enc && $cipher =~ /des-ede3-cfb/)) { -+ die "Implementation lacks support for TDES OFB and TDES CFB in encryption mode - the problem is that we would need to extract the IV of the last round of encryption which would be the input for the next round - see comments in this script for implementation requirements"; -+ } - $old_old_calc_data = $old_calc_data; - $old_calc_data = $calc_data; - -@@ -1429,7 +1552,7 @@ sub rsa_sigver($$$$$) { - # $7 xq2 - # $8 Xq - # return: string formatted as expected by CAVS --sub rsa_keygen($$$$$$$$) { -+sub rsa_keygen_x931($$$$$$$$) { - my $modulus = shift; - my $e = shift; - my $xp1 = shift; -@@ -1503,21 +1626,23 @@ sub rngx931($$$$) { - return $out; - } - --# DSA PQGGen test -+# DSA PQGen test - # $1 modulus size --# $2 number of rounds to perform the test -+# $2 q size -+# $3 number of rounds to perform the test - # return: string formatted as expected by CAVS --sub dsa_pqggen_driver($$) { -+sub dsa_pqgen_driver($$$) { - my $mod = shift; -+ my $qsize = shift; - my $rounds = shift; - - my $out = ""; - for(my $i=0; $i<$rounds; $i++) { -- my $ret = &$dsa_pqggen($mod); -+ my $ret = &$dsa_pqggen($mod, $qsize, ""); - my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); -- die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" -- if (!defined($P) || !defined($Q) || !defined($G) || -- !defined($Seed) || !defined($c) || !defined($H)); -+ die "Return value does not contain all expected values of P, Q, Seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || -+ !defined($Seed) || !defined($c)); - - # now change the counter to decimal as CAVS wants decimal - # counter value although all other is HEX -@@ -1525,15 +1650,166 @@ sub dsa_pqggen_driver($$) { - - $out .= "P = $P\n"; - $out .= "Q = $Q\n"; -- $out .= "G = $G\n"; -- $out .= "Seed = $Seed\n"; -- $out .= "c = $c\n"; -- $out .= "H = $H\n\n"; -+ $out .= "domain_parameter_seed = $Seed\n"; -+ $out .= "counter = $c\n\n"; - } - - return $out; - } - -+# DSA GGen test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# return: string formatted as expected by CAVS -+sub dsa_ggen_driver($$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_ggen($mod, $qsize, $p, $q); -+ my ($P, $Q, $G) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G for dsa_ggen" -+ if (!defined($P) || !defined($Q) || !defined($G)); -+ -+ $out .= "G = $G\n\n"; -+ -+ return $out; -+} -+ -+sub hexcomp($$) { -+ my $a = lc shift; -+ my $b = lc shift; -+ -+ if (length $a < length $b) { -+ my $c = $a; -+ $a = $b; -+ $b = $a; -+ } -+ -+ while (length $b < length $a) { -+ $b = "00$b"; -+ } -+ -+ return $a eq $b; -+} -+ -+# DSA PQVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 seed in hex form -+# $6 c decimal counter -+# return: string formatted as expected by CAVS -+sub dsa_pqver_driver($$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $seed = shift; -+ my $c = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2)); -+ -+ $c2 = hex($c2); -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($seed, $seed2) && $c == $c2) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ return $out; -+} -+ -+# DSA PQGVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 g in hex form -+# $6 seed in hex form -+# $7 c decimal counter -+# $8 h in hex form -+# return: string formatted as expected by CAVS -+sub dsa_pqgver_driver($$$$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $seed = shift; -+ my $c = shift; -+ my $h = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c, H for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2) || !defined($h2)); -+ -+ -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ $out .= "H = $h\n"; -+ -+ $c2 = hex($c2); -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($G, $g) && hexcomp($seed, $seed2) && -+ $c == $c2 && hex($h) == hex($h2)) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ -+ return $out; -+} -+ -+# DSA Keypair test -+# $1 modulus size -+# $2 q size -+# $3 number of rounds to perform the test -+# return: string formatted as expected by CAVS -+sub dsa_keypair_driver($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $rounds = shift; -+ -+ my $out = ""; -+ my $tmpkeyfile = "dsa_siggen.tmp.$$"; -+ my %pqg = &$gen_dsakey($mod, $qsize, $tmpkeyfile); -+ $out .= "P = " . $pqg{'P'} . "\n"; -+ $out .= "Q = " . $pqg{'Q'} . "\n"; -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ unlink($tmpkeyfile); -+ -+ for(my $i=0; $i<$rounds; $i++) { -+ my $ret = &$gen_dsakey_domain($pqg{'P'}, $pqg{'Q'}, $pqg{'G'}); -+ my ($X, $Y) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of X, Y for gen_dsakey_domain" -+ if (!defined($X) || !defined($Y)); -+ -+ $out .= "X = $X\n"; -+ $out .= "Y = $Y\n\n"; -+ } -+ -+ return $out; -+} - - # DSA SigGen test - # $1: Message to be signed in hex form -@@ -1598,6 +1874,53 @@ sub dsa_sigver($$$$$$$$) { - return $out; - } - -+# RSA Keygen RPP test -+# $1 modulus size -+# $2 number of rounds to perform the test -+# return: string formatted as expected by CAVS -+sub rsa_keygen_driver($$) { -+ my $mod = shift; -+ my $rounds = shift; -+ -+ my $out = ""; -+ -+ for(my $i=0; $i<$rounds; $i++) { -+ my $ret = &$rsa_keygen($mod); -+ my ($e, $p, $q, $n, $d) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of e, p, q, n, d for rsa_keygen" -+ if (!defined($e) || !defined($p) || !defined($q) || !defined($n) || !defined($d)); -+ -+ $out .= "e = $e\n"; -+ $out .= "p = $p\n"; -+ $out .= "q = $q\n"; -+ $out .= "n = $n\n"; -+ $out .= "d = $d\n\n"; -+ } -+ -+ return $out; -+} -+ -+# RSA RPP Keygen KAT test -+# $1 modulus size -+# $2 p in hex form -+# $3 q in hex form -+# return: string formatted as expected by CAVS -+sub rsa_keygen_kat_driver($$$) { -+ my $mod = shift; -+ my $p = shift; -+ my $q = shift; -+ -+ my $out = ""; -+ my $ret = &$rsa_keygen_kat($mod, $p, $q); -+ my ($Result) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of Result for rsa_keygen_kat" -+ if (!defined($Result)); -+ -+ $out .= "Result = $Result\n\n"; -+ return $out; -+} -+ -+ - ############################################################## - # Parser of input file and generator of result file - # -@@ -1658,12 +1981,18 @@ sub parse($$) { - my $klen = ""; - my $tlen = ""; - my $modulus = ""; -+ my $qsize = ""; - my $capital_n = 0; -+ my $num = 0; - my $capital_p = ""; - my $capital_q = ""; - my $capital_g = ""; - my $capital_y = ""; - my $capital_r = ""; -+ my $capital_h = ""; -+ my $c = ""; -+ my $prandom = ""; -+ my $qrandom = ""; - my $xp1 = ""; - my $xp2 = ""; - my $Xp = ""; -@@ -1700,7 +2029,7 @@ sub parse($$) { - - ##### Extract cipher - # XXX there may be more - to be added -- if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) { -+ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyGen - Random Probably Prime|KeyPair|PQGVer)/) { - if ($tmpline =~ /CBC/) { $mode="cbc"; } - elsif ($tmpline =~ /ECB/) { $mode="ecb"; } - elsif ($tmpline =~ /OFB/) { $mode="ofb"; } -@@ -1749,7 +2078,23 @@ sub parse($$) { - - if ($tt == 0) { - ##### Identify the test type -- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { -+ if ($tmpline =~ /KeyGen - Random Probably Prime Known Answer Test/) { -+ $tt = 19; -+ die "Interface function rsa_keygen_kat for RSA key generation KAT not defined for tested library" -+ if (!defined($rsa_keygen_kat)); -+ } elsif ($tmpline =~ /KeyGen - Random Probably Prime Test/) { -+ $tt = 18; -+ die "Interface function rsa_keygen for RSA key generation not defined for tested library" -+ if (!defined($rsa_keygen)); -+ } elsif ($tmpline =~ /PQGVer/) { -+ $tt = 16; -+ die "Interface function for DSA PQGVer testing not defined for tested library" -+ if (!defined($dsa_pqggen)); -+ } elsif ($tmpline =~ /KeyPair/) { -+ $tt = 14; -+ die "Interface function dsa_keygen for DSA key generation not defined for tested library" -+ if (!defined($gen_dsakey_domain)); -+ } elsif ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { - $tt = 13; - die "Interface function rsa_derive for RSA key generation not defined for tested library" - if (!defined($rsa_derive)); -@@ -1760,11 +2105,11 @@ sub parse($$) { - } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { - $tt = 11; - die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" -- if (!defined($dsa_sign) || !defined($gen_rsakey)); -+ if (!defined($dsa_sign) || !defined($gen_dsakey)); - } elsif ($tmpline =~ /PQGGen/) { - $tt = 10; - die "Interface function for DSA PQGGen testing not defined for tested library" -- if (!defined($dsa_pqggen)); -+ if (!defined($dsa_pqggen) || !defined($dsa_ggen)); - } elsif ($tmpline =~ /Hash sizes tested/) { - $tt = 9; - die "Interface function hmac for HMAC testing not defined for tested library" -@@ -1792,7 +2137,7 @@ sub parse($$) { - } elsif ($tmpline =~ /Monte|MCT|Carlo/) { - $tt = 2; - die "Interface function state_cipher for Stateful Cipher operation defined for tested library" -- if (!defined($state_cipher) || !defined($state_cipher_des)); -+ if (!defined($state_cipher) && !defined($state_cipher_des)); - } elsif ($cipher =~ /^sha/) { - $tt = 3; - die "Interface function hash for Hashing not defined for tested library" -@@ -1875,18 +2220,44 @@ sub parse($$) { - die "Msg/Seed seen twice - input file crap" if ($pt ne ""); - $pt=$2; - } -- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ elsif ($line =~ /^\[A.2.1\s.*\]$/) { # found in DSA2 PQGGen request -+ $out .= $line . "\n"; # print it -+ if ($tt == 10) { -+ # now generate G from PQ -+ $tt = 15; -+ } -+ } -+ elsif ($line =~ /^\[A.2.2\s.*\]$/) { # found in DSA2 PQGVer request -+ $out .= $line . "\n"; # print it -+ if ($tt == 16) { -+ # now verify PQG -+ $tt = 17; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*L=([0-9]*),\s*N=([0-9]*).*\]$/) { # found in DSA2 requests - $modulus = $1; -+ $qsize = $2; - $out .= $line . "\n\n"; # print it -+ # clear eventual PQG -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; - # generate the private key with given bit length now - # as we have the required key length in bit - if ($tt == 11) { - $dsa_keyfile = "dsa_siggen.tmp.$$"; -- my %pqg = &$gen_dsakey($dsa_keyfile); -+ my %pqg = &$gen_dsakey($modulus, $qsize, $dsa_keyfile); - $out .= "P = " . $pqg{'P'} . "\n"; - $out .= "Q = " . $pqg{'Q'} . "\n"; -- $out .= "G = " . $pqg{'G'} . "\n"; -- } elsif ( $tt == 5 ) { -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ $modulus = $1; -+ $out .= $line . "\n\n"; # print it -+ # generate the private key with given bit length now -+ # as we have the required key length in bit -+ if ( $tt == 5 ) { - # XXX maybe a secure temp file name is better here - # but since it is not run on a security sensitive - # system, I hope that this is fine -@@ -1907,6 +2278,9 @@ sub parse($$) { - } - elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests - $e=$1; -+ if ($tt == 19) { -+ $out .= $line . "\n"; # print it -+ } - } - elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests - die "S seen twice - input file crap" if ($signature ne ""); -@@ -1932,11 +2306,16 @@ sub parse($$) { - if ($tlen ne ""); - $tlen=$1; - } -- elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen -+ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair - die "N seen twice - check input file" - if ($capital_n); - $capital_n = $1; - } -+ elsif ($line =~ /^Num\s*=\s*(.*)/) { #DSA PQGGen -+ die "Num seen twice - check input file" -+ if ($num); -+ $num = $1; -+ } - elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer - die "P seen twice - check input file" - if ($capital_p); -@@ -1965,6 +2344,16 @@ sub parse($$) { - if ($capital_r); - $capital_r = $1; - } -+ elsif ($line =~ /^H\s*=\s*(.*)/) { #DSA PQGVer -+ die "H seen twice - check input file" -+ if ($capital_h); -+ $capital_h = $1; -+ } -+ elsif ($line =~ /^c\s*=\s*(.*)/) { #DSA PQGVer -+ die "c seen twice - check input file" -+ if ($c); -+ $c = $1; -+ } - elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen - die "xp1 seen twice - check input file" - if ($xp1); -@@ -1995,6 +2384,22 @@ sub parse($$) { - if ($Xq); - $Xq = $1; - } -+ elsif ($line =~ /^prandom\s*=\s*(.*)/) { #RSA key gen KAT -+ die "prandom seen twice - check input file" -+ if ($prandom); -+ $prandom = $1; -+ $out .= $line . "\n"; # print it -+ } -+ elsif ($line =~ /^qrandom\s*=\s*(.*)/) { #RSA key gen KAT -+ die "qrandom seen twice - check input file" -+ if ($qrandom); -+ $qrandom = $1; -+ $out .= $line . "\n"; # print it -+ } -+ elsif ($tt == 19 && $line =~ /^ / && $qrandom eq "") { #RSA key gen KAT -+ $qrandom = "00"; -+ $out .= $line . "\n"; # print it -+ } - else { - $out .= $line . "\n"; - } -@@ -2074,11 +2479,10 @@ sub parse($$) { - } - } - elsif ($tt == 10) { -- if ($modulus ne "" && $capital_n > 0) { -- $out .= dsa_pqggen_driver($modulus, $capital_n); -- #$mod is not resetted -- $capital_n = 0; -- } -+ if ($modulus ne "" && $qsize ne "" && $num > 0) { -+ $out .= dsa_pqgen_driver($modulus, $qsize, $num); -+ $num = 0; -+ } - } - elsif ($tt == 11) { - if ($pt ne "" && $dsa_keyfile ne "") { -@@ -2124,7 +2528,7 @@ sub parse($$) { - $xq1 ne "" && - $xq2 ne "" && - $Xq ne "") { -- $out .= rsa_keygen($modulus, -+ $out .= rsa_keygen_x931($modulus, - $e, - $xp1, - $xp2, -@@ -2141,6 +2545,96 @@ sub parse($$) { - $Xq = ""; - } - } -+ elsif ($tt == 14) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_n > 0) { -+ $out .= dsa_keypair_driver($modulus, -+ $qsize, -+ $capital_n); -+ $capital_n = 0; -+ } -+ } -+ elsif ($tt == 15) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "") { -+ $out .= dsa_ggen_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q); -+ $capital_p = ""; -+ $capital_q = ""; -+ $num--; -+ } -+ } -+ elsif ($tt == 16) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $pt ne "" && -+ $c ne "") { -+ $out .= dsa_pqver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $pt, -+ $c); -+ $capital_p = ""; -+ $capital_q = ""; -+ $pt = ""; -+ $c = ""; -+ } -+ } -+ elsif ($tt == 17) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $capital_g ne "" && -+ $pt ne "" && -+ $c ne "" && -+ $capital_h ne "") { -+ $out .= dsa_pqgver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $capital_g, -+ $pt, -+ $c, -+ $capital_h); -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; -+ $pt = ""; -+ $c = ""; -+ $capital_h = ""; -+ } -+ } -+ elsif ($tt == 18) { -+ if ($modulus ne "" && -+ $capital_n > 0) { -+ $out .= rsa_keygen_driver($modulus, -+ $capital_n); -+ $capital_n = 0; -+ } -+ } -+ elsif ($tt == 19) { -+ if ($modulus ne "" && -+ $e ne "" && -+ $prandom ne "" && -+ $qrandom ne "") { -+ $out .= rsa_keygen_kat_driver($modulus, -+ $e, -+ $prandom, -+ $qrandom); -+ $prandom = ""; -+ $qrandom = ""; -+ $e = ""; -+ } -+ } - elsif ($tt > 0) { - die "Test case $tt not defined"; - } -@@ -2199,10 +2693,14 @@ sub main() { - $state_rng = \&libgcrypt_state_rng; - $hmac = \&libgcrypt_hmac; - $dsa_pqggen = \&libgcrypt_dsa_pqggen; -+ $dsa_ggen = \&libgcrypt_dsa_ggen; - $gen_dsakey = \&libgcrypt_gen_dsakey; -+ $gen_dsakey_domain = \&libgcrypt_gen_dsakey_domain; - $dsa_sign = \&libgcrypt_dsa_sign; - $dsa_verify = \&libgcrypt_dsa_verify; - $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; -+ $rsa_keygen = \&libgcrypt_rsa_keygen; -+ $rsa_keygen_kat = \&libgcrypt_rsa_keygen_kat; - } else { - die "Invalid interface option given"; - } -diff -up libgcrypt-1.5.3/tests/cavs_tests.sh.cavs libgcrypt-1.5.3/tests/cavs_tests.sh ---- libgcrypt-1.5.3/tests/cavs_tests.sh.cavs 2013-05-22 18:02:55.000000000 +0200 -+++ libgcrypt-1.5.3/tests/cavs_tests.sh 2014-09-26 17:45:38.434674884 +0200 -@@ -55,7 +55,7 @@ function run_one_test () { - [ -d "$respdir" ] || mkdir "$respdir" - [ -f "$rspfile" ] && rm "$rspfile" - -- if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then -+ if echo "$reqfile" | grep '/DSA.\?/req/' >/dev/null 2>/dev/null; then - dflag="-D" - fi - -diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c ---- libgcrypt-1.5.3/tests/fipsdrv.c.cavs 2013-07-25 11:10:04.000000000 +0200 -+++ libgcrypt-1.5.3/tests/fipsdrv.c 2014-10-21 09:30:30.796777225 +0200 -@@ -893,6 +893,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) - die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); - - p = buf; -+ while (*p) -+ *p++ = tolower(*p); -+ p = buf; - if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) - p += 2; - -@@ -1346,6 +1349,69 @@ run_rsa_derive (const void *data, size_t - } - - -+/* Generate RSA key using the S-expression in (DATA,DATALEN). This -+ S-expression is used directly as input to gcry_pk_genkey. The -+ result is printed to stdout with one parameter per line in hex -+ format and in this order: e, p, q, n, d. */ -+static void -+run_rsa_keygen (const void *data, size_t datalen, int test) -+{ -+ gpg_error_t err; -+ gcry_sexp_t s_keyspec, s_key, s_top, l1; -+ gcry_mpi_t mpi; -+ const char *parmlist; -+ int idx; -+ -+ if (!datalen) -+ err = gpg_error (GPG_ERR_NO_DATA); -+ else -+ err = gcry_sexp_new (&s_keyspec, data, datalen, 1); -+ if (err) -+ die ("gcry_sexp_new failed for RSA key generation: %s\n", -+ gpg_strerror (err)); -+ -+ err = gcry_pk_genkey (&s_key, s_keyspec); -+ -+ gcry_sexp_release (s_keyspec); -+ -+ if (test) { -+ if (err) -+ printf("F\n"); -+ else { -+ gcry_sexp_release (s_key); -+ printf("P\n"); -+ } -+ return; -+ } -+ -+ if (err) -+ die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); -+ -+ parmlist = "epqnd"; -+ -+ /* Parse and print the parameters. */ -+ l1 = gcry_sexp_find_token (s_key, "private-key", 0); -+ s_top = gcry_sexp_find_token (l1, "rsa", 0); -+ gcry_sexp_release (l1); -+ if (!s_top) -+ die ("private-key part not found in result\n"); -+ -+ for (idx=0; parmlist[idx]; idx++) -+ { -+ l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1); -+ mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); -+ gcry_sexp_release (l1); -+ if (!mpi) -+ die ("parameter %c missing in private-key\n", parmlist[idx]); -+ print_mpi_line (mpi, 1); -+ gcry_mpi_release (mpi); -+ } -+ -+ gcry_sexp_release (s_top); -+ gcry_sexp_release (s_key); -+} -+ -+ - - static size_t - compute_tag_length (size_t n) -@@ -1675,14 +1741,14 @@ run_rsa_verify (const void *data, size_t - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen (int keysize) -+dsa_gen (int keysize, int qsize) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; - - err = gcry_sexp_build (&keyspec, NULL, -- "(genkey (dsa (nbits %d)(use-fips186-2)))", -- keysize); -+ "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)))", -+ keysize, qsize); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1700,7 +1766,7 @@ dsa_gen (int keysize) - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) -+dsa_gen_with_seed (int keysize, int qsize, const void *seed, size_t seedlen) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; -@@ -1709,10 +1775,11 @@ dsa_gen_with_seed (int keysize, const vo - "(genkey" - " (dsa" - " (nbits %d)" -- " (use-fips186-2)" -+ " (qbits %d)" -+ " (use-fips186)" - " (derive-parms" - " (seed %b))))", -- keysize, (int)seedlen, seed); -+ keysize, qsize, (int)seedlen, seed); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1720,6 +1787,37 @@ dsa_gen_with_seed (int keysize, const vo - err = gcry_pk_genkey (&key, keyspec); - if (err) - die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); -+ -+ gcry_sexp_release (keyspec); -+ -+ return key; -+} -+ -+/* Generate a DSA key with specified domain parameters and return the complete -+ S-expression. */ -+static gcry_sexp_t -+dsa_gen_key (const char *domain) -+{ -+ gpg_error_t err; -+ gcry_sexp_t keyspec, key, domspec; -+ -+ err = gcry_sexp_new (&domspec, domain, strlen(domain), 0); -+ if (err) -+ die ("gcry_sexp_build failed for domain spec: %s\n", -+ gpg_strerror (err)); -+ -+ err = gcry_sexp_build (&keyspec, NULL, -+ "(genkey" -+ " (dsa" -+ " (use-fips186)" -+ " %S))", -+ domspec); -+ if (err) -+ die ("gcry_sexp_build failed for DSA key generation: %s\n", -+ gpg_strerror (err)); -+ err = gcry_pk_genkey (&key, keyspec); -+ if (err) -+ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); - - gcry_sexp_release (keyspec); - -@@ -1732,7 +1830,7 @@ dsa_gen_with_seed (int keysize, const vo - with one parameter per line in hex format using this order: p, q, - g, seed, counter, h. */ - static void --print_dsa_domain_parameters (gcry_sexp_t key) -+print_dsa_domain_parameters (gcry_sexp_t key, int print_misc) - { - gcry_sexp_t l1, l2; - gcry_mpi_t mpi; -@@ -1768,6 +1866,9 @@ print_dsa_domain_parameters (gcry_sexp_t - } - gcry_sexp_release (l1); - -+ if (!print_misc) -+ return; -+ - /* Extract the seed values. */ - l1 = gcry_sexp_find_token (key, "misc-key-info", 0); - if (!l1) -@@ -1819,38 +1920,106 @@ print_dsa_domain_parameters (gcry_sexp_t - } - - --/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+/* Print just the XY private key parameters. KEY -+ is the complete key as returned by dsa_gen. We print to stdout -+ with one parameter per line in hex format using this order: x, y. */ -+static void -+print_dsa_xy (gcry_sexp_t key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t mpi; -+ int idx; -+ -+ l1 = gcry_sexp_find_token (key, "private-key", 0); -+ if (!l1) -+ die ("private key not found in genkey result\n"); -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("returned private key not formed as expected\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ /* Extract the parameters from the S-expression and print them to stdout. */ -+ for (idx=0; "xy"[idx]; idx++) -+ { -+ l2 = gcry_sexp_find_token (l1, "xy"+idx, 1); -+ if (!l2) -+ die ("no %c parameter in returned public key\n", "xy"[idx]); -+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); -+ if (!mpi) -+ die ("no value for %c parameter in returned private key\n","xy"[idx]); -+ gcry_sexp_release (l2); -+ if (standalone_mode) -+ printf ("%c = ", "XY"[idx]); -+ print_mpi_line (mpi, 1); -+ gcry_mpi_release (mpi); -+ } -+ -+ gcry_sexp_release (l1); -+} -+ -+ -+/* Generate DSA pq domain parameters for a modulus size of KEYSIZE. The - result is printed to stdout with one parameter per line in hex -- format and in this order: p, q, g, seed, counter, h. If SEED is -+ format and in this order: p, q, seed, counter. If SEED is - not NULL this seed value will be used for the generation. */ - static void --run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) -+run_dsa_pqg_gen (int keysize, int qsize, const void *seed, size_t seedlen) - { - gcry_sexp_t key; - - if (seed) -- key = dsa_gen_with_seed (keysize, seed, seedlen); -+ key = dsa_gen_with_seed (keysize, qsize, seed, seedlen); - else -- key = dsa_gen (keysize); -- print_dsa_domain_parameters (key); -+ key = dsa_gen (keysize, qsize); -+ print_dsa_domain_parameters (key, 1); -+ gcry_sexp_release (key); -+} -+ -+ -+/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+ result is printed to stdout with one parameter per line in hex -+ format and in this order: p, q, g, seed, counter, h. If SEED is -+ not NULL this seed value will be used for the generation. */ -+static void -+run_dsa_g_gen (int keysize, int qsize, const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_domain_parameters (key, 0); -+ gcry_sexp_release (key); -+} -+ -+/* Generate a DSA key with specified domain parameters -+ and print the XY values. */ -+static void -+run_dsa_gen_key (const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_xy (key); -+ - gcry_sexp_release (key); - } - - - /* Generate a DSA key of size of KEYSIZE and write the private key to - FILENAME. Also write the parameters to stdout in the same way as -- run_dsa_pqg_gen. */ -+ run_dsa_g_gen. */ - static void --run_dsa_gen (int keysize, const char *filename) -+run_dsa_gen (int keysize, int qsize, const char *filename) - { - gcry_sexp_t key, private_key; - FILE *fp; - -- key = dsa_gen (keysize); -+ key = dsa_gen (keysize, qsize); - private_key = gcry_sexp_find_token (key, "private-key", 0); - if (!private_key) - die ("private key not found in genkey result\n"); -- print_dsa_domain_parameters (key); -+ print_dsa_domain_parameters (key, 1); - - fp = fopen (filename, "wb"); - if (!fp) -@@ -1863,6 +2032,53 @@ run_dsa_gen (int keysize, const char *fi - } - - -+static int -+dsa_hash_from_key(gcry_sexp_t s_key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t q; -+ unsigned int qbits; -+ -+ l1 = gcry_sexp_find_token (s_key, "public-key", 0); -+ if (!l1) -+ { -+ l1 = gcry_sexp_find_token (s_key, "private-key", 0); -+ if (!l1) -+ die ("neither private nor public key found in the loaded key\n"); -+ } -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("public key not formed as expected - no dsa\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ l2 = gcry_sexp_find_token (l1, "q", 0); -+ if (!l2) -+ die ("public key not formed as expected - no q\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); -+ if (!q) -+ die ("public key not formed as expected - no mpi in q\n"); -+ qbits = gcry_mpi_get_nbits(q); -+ gcry_sexp_release(l1); -+ gcry_mpi_release(q); -+ switch(qbits) -+ { -+ case 160: -+ return GCRY_MD_SHA1; -+ case 224: -+ return GCRY_MD_SHA224; -+ case 256: -+ return GCRY_MD_SHA256; -+ default: -+ die("bad number bits (%d) of q in key\n", qbits); -+ } -+ return GCRY_MD_NONE; -+} -+ - - /* Sign DATA of length DATALEN using the key taken from the S-expression - encoded KEYFILE. */ -@@ -1872,11 +2088,16 @@ run_dsa_sign (const void *data, size_t d - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); -+ -+ gcry_md_hash_buffer (algo, hash, data, datalen); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -1887,8 +2108,6 @@ run_dsa_sign (const void *data, size_t d - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); -- - err = gcry_pk_sign (&s_sig, s_data, s_key); - if (err) - { -@@ -1964,13 +2183,18 @@ run_dsa_verify (const void *data, size_t - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; -+ -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -+ gcry_md_hash_buffer (algo, hash, data, datalen); - /* Note that we can't simply use %b with HASH to build the - S-expression, because that might yield a negative value. */ -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -1981,7 +2205,6 @@ run_dsa_verify (const void *data, size_t - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); - s_sig = read_sexp_from_file (sigfile); - - err = gcry_pk_verify (s_sig, s_data, s_key); -@@ -2014,7 +2237,7 @@ usage (int show_help) - "Run a crypto operation using hex encoded input and output.\n" - "MODE:\n" - " encrypt, decrypt, digest, random, hmac-sha,\n" -- " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" -+ " rsa-{derive,gen,sign,verify}, dsa-{pq-gen,g-gen,gen,sign,verify}\n" - "OPTIONS:\n" - " --verbose Print additional information\n" - " --binary Input and output is in binary form\n" -@@ -2024,6 +2247,7 @@ usage (int show_help) - " --dt DT Use the hex encoded DT for the RNG\n" - " --algo NAME Use algorithm NAME\n" - " --keysize N Use a keysize of N bits\n" -+ " --qize N Use a DSA q parameter size of N bits\n" - " --signature NAME Take signature from file NAME\n" - " --chunk N Read in chunks of N bytes (implies --binary)\n" - " --pkcs1 Use PKCS#1 encoding\n" -@@ -2050,6 +2274,7 @@ main (int argc, char **argv) - const char *dt_string = NULL; - const char *algo_string = NULL; - const char *keysize_string = NULL; -+ const char *qsize_string = NULL; - const char *signature_string = NULL; - FILE *input; - void *data; -@@ -2143,6 +2368,14 @@ main (int argc, char **argv) - keysize_string = *argv; - argc--; argv++; - } -+ else if (!strcmp (*argv, "--qsize")) -+ { -+ argc--; argv++; -+ if (!argc) -+ usage (0); -+ qsize_string = *argv; -+ argc--; argv++; -+ } - else if (!strcmp (*argv, "--signature")) - { - argc--; argv++; -@@ -2406,6 +2639,18 @@ main (int argc, char **argv) - die ("no data available (do not use --chunk)\n"); - run_rsa_derive (data, datalen); - } -+ else if (!strcmp (mode_string, "rsa-keygen")) -+ { -+ if (!data) -+ die ("no data available (do not use --chunk)\n"); -+ run_rsa_keygen (data, datalen, 0); -+ } -+ else if (!strcmp (mode_string, "rsa-keygen-kat")) -+ { -+ if (!data) -+ die ("no data available (do not use --chunk)\n"); -+ run_rsa_keygen (data, datalen, 1); -+ } - else if (!strcmp (mode_string, "rsa-gen")) - { - int keysize; -@@ -2463,23 +2708,49 @@ main (int argc, char **argv) - } - else if (!strcmp (mode_string, "dsa-pqg-gen")) - { -- int keysize; -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ run_dsa_pqg_gen (keysize, qsize, datalen? data:NULL, datalen); -+ } -+ else if (!strcmp (mode_string, "dsa-g-gen")) -+ { -+ int keysize, qsize; -+ -+ keysize = keysize_string? atoi (keysize_string) : 0; -+ if (keysize < 1024 || keysize > 3072) -+ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ if (!key_string) -+ die ("option --key containing pq domain parameters is required in this mode\n"); -+ run_dsa_g_gen (keysize, qsize, key_string); -+ } -+ else if (!strcmp (mode_string, "dsa-gen-key")) -+ { -+ if (!key_string) -+ die ("option --key containing pqg domain parameters is required in this mode\n"); -+ run_dsa_gen_key (key_string); - } - else if (!strcmp (mode_string, "dsa-gen")) - { -- int keysize; -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); - if (!key_string) - die ("option --key is required in this mode\n"); -- run_dsa_gen (keysize, key_string); -+ run_dsa_gen (keysize, qsize, key_string); - } - else if (!strcmp (mode_string, "dsa-sign")) - { diff --git a/libgcrypt-1.6.2-fips-reqs.patch b/libgcrypt-1.6.2-fips-reqs.patch deleted file mode 100644 index 4fa5f33..0000000 --- a/libgcrypt-1.6.2-fips-reqs.patch +++ /dev/null @@ -1,345 +0,0 @@ -diff -up libgcrypt-1.6.2/cipher/dsa.c.fips-reqs libgcrypt-1.6.2/cipher/dsa.c ---- libgcrypt-1.6.2/cipher/dsa.c.fips-reqs 2014-12-08 17:15:07.198102721 +0100 -+++ libgcrypt-1.6.2/cipher/dsa.c 2014-12-08 17:16:59.636645610 +0100 -@@ -66,42 +66,86 @@ static const char *dsa_names[] = - }; - - --/* A sample 1024 bit DSA key used for the selftests. */ -+/* A sample 2048 bit DSA key used for the selftests. */ - static const char sample_secret_key[] = - "(private-key" - " (dsa" --" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" --" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" --" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" --" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)" --" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)" --" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" --" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" --" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" --" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)" --" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" --" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" --" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" --" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)" --" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))"; --/* A sample 1024 bit DSA key used for the selftests (public only). */ -+" (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" -+" 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" -+" 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" -+" 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" -+" 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" -+" eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" -+" 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" -+" 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" -+" 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" -+" 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" -+" 2c8d7469db02e24d592394a7dba069e9#)" -+" (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" -+" 7441a0a5#)" -+" (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" -+" 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" -+" ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" -+" 0df242b75b414df372121e53a553f222f836b000f016485b" -+" 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" -+" 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" -+" 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" -+" ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" -+" 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" -+" 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" -+" 45f322f82e4e85ca3ab85591b3c2a966#)" -+" (y #2452f3ccbe9ed5ca7dc74c602b99226e8f2fab38e7d7ddfb" -+" 75539b17155e9fcfd1aba564eb8535d812c9c2dcf9728444" -+" 1bc482243624c7f457580c1c38a57c46c457392470edb52c" -+" b5a6e03fe6287bb6f49a42a2065a054f030839df1fd3149c" -+" 4ca0531dd8ca8aaa9cc7337193387348336118224545e88c" -+" 80ffd8765d74360333ccab9972779b6525a65bdd0d10c675" -+" c109bbd3e5be4d72ef6eba6e438d5226237db888379c5fcc" -+" 47a3847ff63711baed6d03afe81e694a413b680bd38ab490" -+" 3f8370a707ef551d4941026d9579d691de8edaa16105eb9d" -+" ba3c2f4c1bec508275aa0207e251b5eccb286a4b01d449d3" -+" 0acb673717a0d2fb3b50c893f7dab14f#)" -+" (x #0c4b3089d1b862cb3c436491f0915470c52796e3acbee800" -+" ec55f6cc#)))"; -+/* A sample 2048 bit DSA key used for the selftests (public only). */ - static const char sample_public_key[] = - "(public-key" - " (dsa" --" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" --" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" --" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" --" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)" --" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)" --" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" --" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" --" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" --" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)" --" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" --" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" --" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" --" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))"; -- -+" (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" -+" 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" -+" 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" -+" 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" -+" 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" -+" eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" -+" 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" -+" 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" -+" 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" -+" 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" -+" 2c8d7469db02e24d592394a7dba069e9#)" -+" (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" -+" 7441a0a5#)" -+" (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" -+" 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" -+" ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" -+" 0df242b75b414df372121e53a553f222f836b000f016485b" -+" 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" -+" 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" -+" 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" -+" ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" -+" 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" -+" 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" -+" 45f322f82e4e85ca3ab85591b3c2a966#)" -+" (y #2452f3ccbe9ed5ca7dc74c602b99226e8f2fab38e7d7ddfb" -+" 75539b17155e9fcfd1aba564eb8535d812c9c2dcf9728444" -+" 1bc482243624c7f457580c1c38a57c46c457392470edb52c" -+" b5a6e03fe6287bb6f49a42a2065a054f030839df1fd3149c" -+" 4ca0531dd8ca8aaa9cc7337193387348336118224545e88c" -+" 80ffd8765d74360333ccab9972779b6525a65bdd0d10c675" -+" c109bbd3e5be4d72ef6eba6e438d5226237db888379c5fcc" -+" 47a3847ff63711baed6d03afe81e694a413b680bd38ab490" -+" 3f8370a707ef551d4941026d9579d691de8edaa16105eb9d" -+" ba3c2f4c1bec508275aa0207e251b5eccb286a4b01d449d3" -+" 0acb673717a0d2fb3b50c893f7dab14f#)))"; - - - -@@ -1164,14 +1208,14 @@ dsa_get_nbits (gcry_sexp_t parms) - */ - - static const char * --selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) -+selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey) - { - static const char sample_data[] = - "(data (flags raw)" -- " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4#))"; -+ " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4f1e2d3c4b5a6978879605142#))"; - static const char sample_data_bad[] = - "(data (flags raw)" -- " (value #a0b1c2d3e4f510102030405060708090a1b2c3d4#))"; -+ " (value #a0b1c2d3e4f500102030405060708090a1b2c3d401e2d3c4b5a6978879605142#))"; - - const char *errtxt = NULL; - gcry_error_t err; -@@ -1247,7 +1291,7 @@ selftests_dsa (selftest_report_func_t re - } - - what = "sign"; -- errtxt = selftest_sign_1024 (pkey, skey); -+ errtxt = selftest_sign (pkey, skey); - if (errtxt) - goto failed; - -diff -up libgcrypt-1.6.2/cipher/rsa.c.fips-reqs libgcrypt-1.6.2/cipher/rsa.c ---- libgcrypt-1.6.2/cipher/rsa.c.fips-reqs 2014-12-08 17:15:07.218103174 +0100 -+++ libgcrypt-1.6.2/cipher/rsa.c 2014-12-08 17:20:24.666282521 +0100 -@@ -62,33 +62,57 @@ static const char *rsa_names[] = - }; - - --/* A sample 1024 bit RSA key used for the selftests. */ -+/* A sample 2048 bit RSA key used for the selftests. */ - static const char sample_secret_key[] = - "(private-key" - " (rsa" --" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" --" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" --" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" --" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)" -+" (n #00c9d56d9d90db43d602ed9688138ab2bf6ea10610b27837a714a8ffdd00" -+" ddb493a045cc9690edada9ddc4d6ca0cf0ed4f725e21499a1812158f905a" -+" dbb63399a3e6b4f0c4972126bbe3baf2ffa072da89638e8b3e089d922abe" -+" 16e14315fc57c71f0911671ca996d18b3e8093c159d06d39f2ac95cc1075" -+" e93124d143af68524be716d749656f26c086adc0070ac1e12f8785863bdc" -+" 5a99bee9f9b9e98227510415ab060e765a288d92bdc5b57ba8df4e47a2c1" -+" e752bf47f762e03a6f4d6a4d4ed4b95969fab214c1eee62f95cd9472aee4" -+" db189ac4cd70bdee3116b74965ac40190eb56d83f136bb082f2e4e9262a4" -+" ff50db2045a2eb167af2d528c1fd4e0371#)" - " (e #010001#)" --" (d #046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b11" --" 7d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bd" --" c543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21" --" c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781#)" --" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" --" fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)" --" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" --" 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)" --" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" --" ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))"; --/* A sample 1024 bit RSA key used for the selftests (public only). */ -+" (d #03b1e24a94e50ab21f8619701ec97679be2cf8f733c9331d9e2974dba721" -+" 27e5def480290e78a769f96b19d28397a284868fb614ca9b1fb3a0d7efed" -+" df41451204ce71aceba659f6ed15964ebb317712364e1cfaf2fded77d658" -+" 8561acc49c97c2d7efe75f1534b35bd4f6561e1f468b45590db34553d4d0" -+" c2cb4d806b74e1b2c52740462538865d9792b0aefbbf7b9827f4b3badcb3" -+" 5adab638266a2d2fb8422a7a19142e08848e56af77a66c39b2afafa2e15b" -+" 1a7e4ed1f2c7ed350678c0465d86472af97371b13ef5058662f835ef9087" -+" f6cca8281bbf1b6b155c737b33d9e443350df85e7cc3b507231fb839f41f" -+" 02c654b29017f35d69007c70e13ba0e5#)" -+" (p #00ccbe7b096906ee45bf884738a8f817e5b6ba6755e3e8058bb8e253d68e" -+" ef2ce74f4af74e268d850b3fecc31cd4ebec6ac8722a257dfda67796f01e" -+" cd2857f83730756bbdd47b0c87c56c8740a5bb272c78c9745a545b0b306f" -+" 444afa71e4216166f9ee65de7c04d7fda9155b7fe27aba698672a6068d9b" -+" 9055609e4c5da9b655#)" -+" (q #00fc5c6e16ce1f037bcdf7b372b28f1672b856aef7cd67d84e7d07afd543" -+" 26c335be438f4e2f1c434e6bd2b2ec526d97522bcc5c3a6bf414c674da66" -+" 381c7a3f842fe3f95ab865694606a33779b2a15b58ed5ea75f8c6566bbd1" -+" 2436e637a73d49778a8c34d86929f34d5822b05124b640a886590ab7ba5c" -+" 97da57e836da7a9cad#)" -+" (u #2396c191175e0a83d2dc7b69b2591d3358523f18c709501cb9a1bb4ca238" -+" 404c9a8efe9c9092d0719f899950911f348b745311114a70e2f730d88c80" -+" e1cc9ff163171a7d67294ccb4e747be03e9e2ff4678fecb95c001e7ea27b" -+" 92c96f4ce40ef94863cd50225dbfb69d01336af450be86984fca3f3afacf" -+" 0740c4aaadaebebf#)))"; -+/* A sample 2048 bit RSA key used for the selftests (public only). */ - static const char sample_public_key[] = - "(public-key" - " (rsa" --" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" --" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" --" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" --" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)" -+" (n #00c9d56d9d90db43d602ed9688138ab2bf6ea10610b27837a714a8ffdd00" -+" ddb493a045cc9690edada9ddc4d6ca0cf0ed4f725e21499a1812158f905a" -+" dbb63399a3e6b4f0c4972126bbe3baf2ffa072da89638e8b3e089d922abe" -+" 16e14315fc57c71f0911671ca996d18b3e8093c159d06d39f2ac95cc1075" -+" e93124d143af68524be716d749656f26c086adc0070ac1e12f8785863bdc" -+" 5a99bee9f9b9e98227510415ab060e765a288d92bdc5b57ba8df4e47a2c1" -+" e752bf47f762e03a6f4d6a4d4ed4b95969fab214c1eee62f95cd9472aee4" -+" db189ac4cd70bdee3116b74965ac40190eb56d83f136bb082f2e4e9262a4" -+" ff50db2045a2eb167af2d528c1fd4e0371#)" - " (e #010001#)))"; - - -@@ -1610,20 +1634,35 @@ compute_keygrip (gcry_md_hd_t md, gcry_s - */ - - static const char * --selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) -+selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey) - { - static const char sample_data[] = - "(data (flags pkcs1)" -- " (hash sha1 #11223344556677889900aabbccddeeff10203040#))"; -+ " (hash sha256 #11223344556677889900aabbccddeeffa0b0c0d0102030405060708090a1b1c1#))"; - static const char sample_data_bad[] = - "(data (flags pkcs1)" -- " (hash sha1 #11223344556677889900aabbccddeeff80203040#))"; -+ " (hash sha256 #11223344556677889900aabbccddeeffa0b0c0d0102030405060708091a1b1c1#))"; -+ static const char signature_ka[] = -+ "(sig-val \n" -+ " (rsa \n" -+ " (s #0B12D55738B099D401C81BEEDA54E045B4B7D9CDA5A8769E9C484F696A58912A" -+ "1E5DE7E5A2D181DA15A5C254D802AB75F1056E27406850AC7BE310BC32D2CED8" -+ "6697FE84508F7EFFF4D147C52E955A0873EF2F52ED71F2FC9C3C12D4045CB643" -+ "70158378E1494D8FBAD2248B9B64233D2CC2C1932B0531E539DEB07434B76D3B" -+ "6959E8A37E33B234C0C8C2C8FB1D00939239C9C491B2EBEED77BF952B597E11B" -+ "D4ED0C103D2B88BC78B4E505CF9D8D08B585CE3688D4FBE83ED58D1E1341AC4D" -+ "7C5EFF3CBC565CC7AE61C2F568426763A5239D31C1FFFD366984901679A343C4" -+ "01BB778BBA5E533B7875BA658A19AA9E56170F4A28E4322BF1621175FB06463E#)\n" -+ " )\n" -+ " )\n"; - - const char *errtxt = NULL; - gcry_error_t err; - gcry_sexp_t data = NULL; - gcry_sexp_t data_bad = NULL; - gcry_sexp_t sig = NULL; -+ char buf[1024]; -+ size_t len; - - err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data)); - if (!err) -@@ -1641,6 +1680,12 @@ selftest_sign_1024 (gcry_sexp_t pkey, gc - errtxt = "signing failed"; - goto leave; - } -+ len = sexp_sprint (sig, GCRYSEXP_FMT_ADVANCED, buf, sizeof(buf)); -+ if (len != sizeof (signature_ka) - 1 || memcmp (buf, signature_ka, len) != 0) -+ { -+ errtxt = "signature KAT failed"; -+ goto leave; -+ } - err = _gcry_pk_verify (sig, data, pkey); - if (err) - { -@@ -1697,11 +1742,11 @@ extract_a_from_sexp (gcry_sexp_t encr_da - - - static const char * --selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) -+selftest_encr (gcry_sexp_t pkey, gcry_sexp_t skey) - { - const char *errtxt = NULL; - gcry_error_t err; -- const unsigned int nbits = 1000; /* Encrypt 1000 random bits. */ -+ const unsigned int nbits = 2000; /* Encrypt 2000 random bits. */ - gcry_mpi_t plaintext = NULL; - gcry_sexp_t plain = NULL; - gcry_sexp_t encr = NULL; -@@ -1822,12 +1867,12 @@ selftests_rsa (selftest_report_func_t re - } - - what = "sign"; -- errtxt = selftest_sign_1024 (pkey, skey); -+ errtxt = selftest_sign (pkey, skey); - if (errtxt) - goto failed; - - what = "encrypt"; -- errtxt = selftest_encr_1024 (pkey, skey); -+ errtxt = selftest_encr (pkey, skey); - if (errtxt) - goto failed; - -diff -up libgcrypt-1.6.2/random/drbg.c.fips-reqs libgcrypt-1.6.2/random/drbg.c -diff -up libgcrypt-1.6.2/src/visibility.c.fips-reqs libgcrypt-1.6.2/src/visibility.c ---- libgcrypt-1.6.2/src/visibility.c.fips-reqs 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/src/visibility.c 2014-12-08 17:23:06.530943221 +0100 -@@ -1259,6 +1259,8 @@ gcry_kdf_derive (const void *passphrase, - unsigned long iterations, - size_t keysize, void *keybuffer) - { -+ if (!fips_is_operational ()) -+ return gpg_error (fips_not_operational ()); - return gpg_error (_gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, - salt, saltlen, iterations, - keysize, keybuffer)); -@@ -1314,6 +1316,13 @@ void - gcry_mpi_randomize (gcry_mpi_t w, - unsigned int nbits, enum gcry_random_level level) - { -+ if (!fips_is_operational ()) -+ { -+ (void)fips_not_operational (); -+ fips_signal_fatal_error ("called in non-operational state"); -+ fips_noreturn (); -+ } -+ - _gcry_mpi_randomize (w, nbits, level); - } - -@@ -1339,6 +1348,8 @@ gcry_prime_generate (gcry_mpi_t *prime, - gcry_random_level_t random_level, - unsigned int flags) - { -+ if (!fips_is_operational ()) -+ return gpg_error (fips_not_operational ()); - return gpg_error (_gcry_prime_generate (prime, prime_bits, factor_bits, - factors, cb_func, cb_arg, - random_level, flags)); diff --git a/libgcrypt-1.6.2-fips-test.patch b/libgcrypt-1.6.2-fips-test.patch deleted file mode 100644 index b21d4a1..0000000 --- a/libgcrypt-1.6.2-fips-test.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -up libgcrypt-1.6.2/tests/basic.c.fips-test libgcrypt-1.6.2/tests/basic.c ---- libgcrypt-1.6.2/tests/basic.c.fips-test 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/tests/basic.c 2014-12-08 16:54:07.767619682 +0100 -@@ -582,6 +582,14 @@ check_ctr_cipher (void) - if (!tv[i].algo) - continue; - -+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ tv[i].algo); -+ continue; -+ } -+ - err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); - if (!err) - err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); diff --git a/libgcrypt-1.6.3-aliasing.patch b/libgcrypt-1.6.3-aliasing.patch deleted file mode 100644 index 9282944..0000000 --- a/libgcrypt-1.6.3-aliasing.patch +++ /dev/null @@ -1,177 +0,0 @@ -diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhelp.h ---- libgcrypt-1.6.3/cipher/bufhelp.h.aliasing 2015-02-27 10:54:03.000000000 +0100 -+++ libgcrypt-1.6.3/cipher/bufhelp.h 2015-03-13 15:03:43.301749751 +0100 -@@ -80,7 +80,7 @@ do_bytes: - for (; len; len--) - *dst++ = *src++; - #endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/ --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - /* Optimized function for buffer xoring */ -@@ -117,7 +117,7 @@ do_bytes: - /* Handle tail. */ - for (; len; len--) - *dst++ = *src1++ ^ *src2++; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - /* Optimized function for buffer xoring with two destination buffers. Used -@@ -155,7 +155,7 @@ do_bytes: - /* Handle tail. */ - for (; len; len--) - *dst1++ = (*dst2++ ^= *src++); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - /* Optimized function for combined buffer xoring and copying. Used by mainly -@@ -208,7 +208,7 @@ do_bytes: - *dst_xor++ = *srcdst_cpy ^ *src_xor++; - *srcdst_cpy++ = temp; - } --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - /* Optimized function for combined buffer xoring and copying. Used by mainly -@@ -234,7 +234,7 @@ buf_eq_const(const void *_a, const void - diff -= !!(a[i] - b[i]); - - return !diff; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - #ifndef BUFHELP_FAST_UNALIGNED_ACCESS -@@ -246,14 +246,14 @@ static inline u32 buf_get_be32(const voi - const byte *in = _buf; - return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \ - ((u32)in[2] << 8) | (u32)in[3]; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline u32 buf_get_le32(const void *_buf) - { - const byte *in = _buf; - return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \ - ((u32)in[1] << 8) | (u32)in[0]; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_be32(void *_buf, u32 val) - { -@@ -262,7 +262,7 @@ static inline void buf_put_be32(void *_b - out[1] = val >> 16; - out[2] = val >> 8; - out[3] = val; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_le32(void *_buf, u32 val) - { -@@ -271,7 +271,7 @@ static inline void buf_put_le32(void *_b - out[2] = val >> 16; - out[1] = val >> 8; - out[0] = val; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - #ifdef HAVE_U64_TYPEDEF - /* Functions for loading and storing unaligned u64 values of different -@@ -283,7 +283,7 @@ static inline u64 buf_get_be64(const voi - ((u64)in[2] << 40) | ((u64)in[3] << 32) | \ - ((u64)in[4] << 24) | ((u64)in[5] << 16) | \ - ((u64)in[6] << 8) | (u64)in[7]; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline u64 buf_get_le64(const void *_buf) - { -@@ -292,7 +292,7 @@ static inline u64 buf_get_le64(const voi - ((u64)in[5] << 40) | ((u64)in[4] << 32) | \ - ((u64)in[3] << 24) | ((u64)in[2] << 16) | \ - ((u64)in[1] << 8) | (u64)in[0]; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_be64(void *_buf, u64 val) - { -@@ -305,7 +305,7 @@ static inline void buf_put_be64(void *_b - out[5] = val >> 16; - out[6] = val >> 8; - out[7] = val; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_le64(void *_buf, u64 val) - { -@@ -318,7 +318,7 @@ static inline void buf_put_le64(void *_b - out[2] = val >> 16; - out[1] = val >> 8; - out[0] = val; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - #endif /*HAVE_U64_TYPEDEF*/ - - #else /*BUFHELP_FAST_UNALIGNED_ACCESS*/ -@@ -328,24 +328,24 @@ static inline void buf_put_le64(void *_b - static inline u32 buf_get_be32(const void *_buf) - { - return be_bswap32(*(const u32 *)_buf); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline u32 buf_get_le32(const void *_buf) - { - return le_bswap32(*(const u32 *)_buf); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_be32(void *_buf, u32 val) - { - u32 *out = _buf; - *out = be_bswap32(val); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_le32(void *_buf, u32 val) - { - u32 *out = _buf; - *out = le_bswap32(val); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - #ifdef HAVE_U64_TYPEDEF - /* Functions for loading and storing unaligned u64 values of different -@@ -353,24 +353,24 @@ static inline void buf_put_le32(void *_b - static inline u64 buf_get_be64(const void *_buf) - { - return be_bswap64(*(const u64 *)_buf); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline u64 buf_get_le64(const void *_buf) - { - return le_bswap64(*(const u64 *)_buf); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_be64(void *_buf, u64 val) - { - u64 *out = _buf; - *out = be_bswap64(val); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_le64(void *_buf, u64 val) - { - u64 *out = _buf; - *out = le_bswap64(val); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - #endif /*HAVE_U64_TYPEDEF*/ - - #endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ diff --git a/libgcrypt-1.6.3-rsa-fips-keygen.patch b/libgcrypt-1.6.3-rsa-fips-keygen.patch deleted file mode 100644 index a229039..0000000 --- a/libgcrypt-1.6.3-rsa-fips-keygen.patch +++ /dev/null @@ -1,382 +0,0 @@ -Add FIPS 186-4 compliant RSA probable prime key generator. - -Signed-off-by: Tomáš Mráz - -diff -up libgcrypt-1.6.3/cipher/primegen.c.fips-keygen libgcrypt-1.6.3/cipher/primegen.c ---- libgcrypt-1.6.3/cipher/primegen.c.fips-keygen 2015-03-06 16:38:56.698052602 +0100 -+++ libgcrypt-1.6.3/cipher/primegen.c 2015-03-06 16:45:45.848193024 +0100 -@@ -1199,6 +1199,25 @@ _gcry_prime_check (gcry_mpi_t x, unsigne - return GPG_ERR_NO_PRIME; - } - -+/* Check whether the number X is prime according to FIPS 186-4 table C.2. */ -+gcry_err_code_t -+_gcry_fips186_4_prime_check (gcry_mpi_t x, unsigned int bits) -+{ -+ gcry_err_code_t ec = GPG_ERR_NO_ERROR; -+ -+ switch (mpi_cmp_ui (x, 2)) -+ { -+ case 0: return ec; /* 2 is a prime */ -+ case -1: return GPG_ERR_NO_PRIME; /* Only numbers > 1 are primes. */ -+ } -+ -+ /* We use 5 or 4 rounds as specified in table C.2 */ -+ if (! check_prime (x, mpi_const (MPI_C_TWO), bits > 1024 ? 4 : 5, NULL, NULL)) -+ ec = GPG_ERR_NO_PRIME; -+ -+ return ec; -+} -+ - /* Find a generator for PRIME where the factorization of (prime-1) is - in the NULL terminated array FACTORS. Return the generator as a - newly allocated MPI in R_G. If START_G is not NULL, use this as s -diff -up libgcrypt-1.6.3/cipher/rsa.c.fips-keygen libgcrypt-1.6.3/cipher/rsa.c ---- libgcrypt-1.6.3/cipher/rsa.c.fips-keygen 2015-03-06 16:38:56.661052411 +0100 -+++ libgcrypt-1.6.3/cipher/rsa.c 2015-03-06 16:38:56.699052607 +0100 -@@ -339,6 +339,279 @@ generate_std (RSA_secret_key *sk, unsign - } - - -+/**************** -+ * Generate a key pair with a key of size NBITS. -+ * USE_E = 0 let Libcgrypt decide what exponent to use. -+ * = 1 request the use of a "secure" exponent; this is required by some -+ * specification to be 65537. -+ * > 2 Use this public exponent. If the given exponent -+ * is not odd one is internally added to it. -+ * TESTPARMS: If set, do not generate but test whether the p,q is probably prime -+ * Returns key with zeroes to not break code calling this function. -+ * TRANSIENT_KEY: If true, generate the primes using the standard RNG. -+ * Returns: 2 structures filled with all needed values -+ */ -+static gpg_err_code_t -+generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, -+ gcry_sexp_t testparms, int transient_key) -+{ -+ gcry_mpi_t p, q; /* the two primes */ -+ gcry_mpi_t d; /* the private key */ -+ gcry_mpi_t u; -+ gcry_mpi_t p1, q1; -+ gcry_mpi_t n; /* the public key */ -+ gcry_mpi_t e; /* the exponent */ -+ gcry_mpi_t g; -+ gcry_mpi_t minp; -+ gcry_mpi_t diff, mindiff; -+ gcry_random_level_t random_level; -+ unsigned int pbits = nbits/2; -+ unsigned int i; -+ int pqswitch; -+ gpg_err_code_t ec = GPG_ERR_NO_PRIME; -+ -+ if (nbits < 1024 || (nbits & 0x1FF)) -+ return GPG_ERR_INV_VALUE; -+ if (_gcry_enforced_fips_mode() && nbits != 2048 && nbits != 3072) -+ return GPG_ERR_INV_VALUE; -+ -+ /* The random quality depends on the transient_key flag. */ -+ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; -+ -+ if (testparms) -+ { -+ /* Parameters to derive the key are given. */ -+ /* Note that we explicitly need to setup the values of tbl -+ because some compilers (e.g. OpenWatcom, IRIX) don't allow -+ to initialize a structure with automatic variables. */ -+ struct { const char *name; gcry_mpi_t *value; } tbl[] = { -+ { "e" }, -+ { "p" }, -+ { "q" }, -+ { NULL } -+ }; -+ int idx; -+ gcry_sexp_t oneparm; -+ -+ tbl[0].value = &e; -+ tbl[1].value = &p; -+ tbl[2].value = &q; -+ -+ for (idx=0; tbl[idx].name; idx++) -+ { -+ oneparm = sexp_find_token (testparms, tbl[idx].name, 0); -+ if (oneparm) -+ { -+ *tbl[idx].value = sexp_nth_mpi (oneparm, 1, -+ GCRYMPI_FMT_USG); -+ sexp_release (oneparm); -+ } -+ } -+ for (idx=0; tbl[idx].name; idx++) -+ if (!*tbl[idx].value) -+ break; -+ if (tbl[idx].name) -+ { -+ /* At least one parameter is missing. */ -+ for (idx=0; tbl[idx].name; idx++) -+ _gcry_mpi_release (*tbl[idx].value); -+ return GPG_ERR_MISSING_VALUE; -+ } -+ } -+ else -+ { -+ if (use_e < 65537) -+ use_e = 65537; /* This is the smallest value allowed by FIPS */ -+ -+ e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB ); -+ -+ use_e |= 1; /* make sure this is odd */ -+ mpi_set_ui (e, use_e); -+ -+ p = mpi_snew (pbits); -+ q = mpi_snew (pbits); -+ } -+ -+ n = mpi_new (nbits); -+ d = mpi_snew (nbits); -+ u = mpi_snew (nbits); -+ -+ /* prepare approximate minimum p and q */ -+ minp = mpi_new (pbits); -+ mpi_set_ui (minp, 0xB504F334); -+ mpi_lshift (minp, minp, pbits - 32); -+ -+ /* prepare minimum p and q difference */ -+ diff = mpi_new (pbits); -+ mindiff = mpi_new (pbits - 99); -+ mpi_set_ui (mindiff, 1); -+ mpi_lshift (mindiff, mindiff, pbits - 100); -+ -+ p1 = mpi_snew (pbits); -+ q1 = mpi_snew (pbits); -+ g = mpi_snew (pbits); -+ -+retry: -+ /* generate p and q */ -+ for (i = 0; i < 5 * pbits; i++) -+ { -+ ploop: -+ if (!testparms) -+ { -+ _gcry_mpi_randomize (p, pbits, random_level); -+ } -+ if (mpi_cmp (p, minp) < 0) -+ { -+ if (testparms) goto err; -+ goto ploop; -+ } -+ -+ mpi_sub_ui (p1, p, 1); -+ if (mpi_gcd (g, p1, e)) -+ { -+ if (_gcry_fips186_4_prime_check (p, pbits) != GPG_ERR_NO_ERROR) -+ { -+ /* not a prime */ -+ if (testparms) goto err; -+ } -+ else -+ break; -+ } -+ else if (testparms) goto err; -+ } -+ if (i >= 5 * pbits) -+ goto err; -+ -+ for (i = 0; i < 5 * pbits; i++) -+ { -+ qloop: -+ if (!testparms) -+ { -+ _gcry_mpi_randomize (q, pbits, random_level); -+ } -+ if (mpi_cmp (q, minp) < 0) -+ { -+ if (testparms) goto err; -+ goto qloop; -+ } -+ if (mpi_cmp (p, q) > 0) -+ { -+ pqswitch = 1; -+ mpi_sub (diff, p, q); -+ } -+ else -+ { -+ pqswitch = 0; -+ mpi_sub (diff, q, p); -+ } -+ if (mpi_cmp (diff, mindiff) < 0) -+ { -+ if (testparms) goto err; -+ goto qloop; -+ } -+ -+ mpi_sub_ui (q1, q, 1); -+ if (mpi_gcd (g, q1, e)) -+ { -+ if (_gcry_fips186_4_prime_check (q, pbits) != GPG_ERR_NO_ERROR) -+ { -+ /* not a prime */ -+ if (testparms) goto err; -+ } -+ else -+ break; -+ } -+ else if (testparms) goto err; -+ } -+ if (i >= 5 * pbits) -+ goto err; -+ -+ if (testparms) -+ { -+ mpi_clear (p); -+ mpi_clear (q); -+ } -+ else -+ { -+ gcry_mpi_t f; -+ -+ if (pqswitch) -+ { -+ gcry_mpi_t tmp; -+ -+ tmp = p; -+ p = q; -+ q = tmp; -+ } -+ -+ f = mpi_snew (nbits); -+ -+ /* calculate the modulus */ -+ mpi_mul(n, p, q); -+ -+ /* calculate the secret key d = e^1 mod phi */ -+ mpi_gcd (g, p1, q1); -+ mpi_fdiv_q (f, p1, g); -+ mpi_mul (f, f, q1); -+ -+ mpi_invm (d, e, f); -+ -+ _gcry_mpi_release (f); -+ -+ if (mpi_get_nbits (d) < pbits) goto retry; -+ -+ /* calculate the inverse of p and q (used for chinese remainder theorem)*/ -+ mpi_invm(u, p, q ); -+ } -+ -+ ec = 0; -+ -+ if( DBG_CIPHER ) -+ { -+ log_mpidump(" p= ", p ); -+ log_mpidump(" q= ", q ); -+ log_mpidump(" n= ", n ); -+ log_mpidump(" e= ", e ); -+ log_mpidump(" d= ", d ); -+ log_mpidump(" u= ", u ); -+ } -+ -+err: -+ -+ _gcry_mpi_release (p1); -+ _gcry_mpi_release (q1); -+ _gcry_mpi_release (g); -+ _gcry_mpi_release (minp); -+ _gcry_mpi_release (mindiff); -+ _gcry_mpi_release (diff); -+ -+ sk->n = n; -+ sk->e = e; -+ sk->p = p; -+ sk->q = q; -+ sk->d = d; -+ sk->u = u; -+ -+ /* Now we can test our keys. */ -+ if (ec || (!testparms && test_keys (sk, nbits - 64))) -+ { -+ _gcry_mpi_release (sk->n); sk->n = NULL; -+ _gcry_mpi_release (sk->e); sk->e = NULL; -+ _gcry_mpi_release (sk->p); sk->p = NULL; -+ _gcry_mpi_release (sk->q); sk->q = NULL; -+ _gcry_mpi_release (sk->d); sk->d = NULL; -+ _gcry_mpi_release (sk->u); sk->u = NULL; -+ if (!ec) -+ { -+ fips_signal_error ("self-test after key generation failed"); -+ return GPG_ERR_SELFTEST_FAILED; -+ } -+ } -+ -+ return ec; -+} -+ -+ - /* Helper for generate_x931. */ - static gcry_mpi_t - gen_x931_parm_xp (unsigned int nbits) -@@ -799,7 +1072,7 @@ rsa_generate (const gcry_sexp_t genparms - } - } - -- if (deriveparms || (flags & PUBKEY_FLAG_USE_X931) || fips_mode ()) -+ if (deriveparms || (flags & PUBKEY_FLAG_USE_X931)) - { - int swapped; - ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped); -@@ -819,9 +1092,14 @@ rsa_generate (const gcry_sexp_t genparms - sexp_release (l1); - } - } -+ deriveparms = (genparms? -+ sexp_find_token (genparms, "test-parms", 0) : NULL); - /* Generate. */ -- ec = generate_std (&sk, nbits, evalue, -- !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); -+ if (deriveparms || fips_mode()) -+ ec = generate_fips (&sk, nbits, evalue, deriveparms, !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); -+ else -+ ec = generate_std (&sk, nbits, evalue, !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); -+ sexp_release (deriveparms); - } - - if (!ec) -diff -up libgcrypt-1.6.3/src/g10lib.h.fips-keygen libgcrypt-1.6.3/src/g10lib.h ---- libgcrypt-1.6.3/src/g10lib.h.fips-keygen 2015-02-23 11:55:58.000000000 +0100 -+++ libgcrypt-1.6.3/src/g10lib.h 2015-03-06 16:38:56.699052607 +0100 -@@ -259,6 +259,9 @@ gpg_err_code_t _gcry_generate_fips186_3_ - int *r_counter, - void **r_seed, size_t *r_seedlen, int *r_hashalgo); - -+gpg_err_code_t _gcry_fips186_4_prime_check -+ (const gcry_mpi_t x, unsigned int bits); -+ - - /* Replacements of missing functions (missing-string.c). */ - #ifndef HAVE_STPCPY -diff -up libgcrypt-1.6.3/tests/keygen.c.fips-keygen libgcrypt-1.6.3/tests/keygen.c ---- libgcrypt-1.6.3/tests/keygen.c.fips-keygen 2015-03-06 16:38:56.661052411 +0100 -+++ libgcrypt-1.6.3/tests/keygen.c 2015-03-06 16:38:56.699052607 +0100 -@@ -215,12 +215,12 @@ check_rsa_keys (void) - - - if (verbose) -- show ("creating 1024 bit RSA key with e=257\n"); -+ show ("creating 1024 bit RSA key with e=65539\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" - " (nbits 4:1024)\n" -- " (rsa-use-e 3:257)\n" -+ " (rsa-use-e 5:65539)\n" - " ))", 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gpg_strerror (rc)); -@@ -229,7 +229,7 @@ check_rsa_keys (void) - if (rc) - die ("error generating RSA key: %s\n", gpg_strerror (rc)); - -- check_generated_rsa_key (key, 257); -+ check_generated_rsa_key (key, 65539); - gcry_sexp_release (key); - - if (verbose) diff --git a/libgcrypt-1.6.5-leak.patch b/libgcrypt-1.6.5-leak.patch deleted file mode 100644 index df51187..0000000 --- a/libgcrypt-1.6.5-leak.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff -up libgcrypt-1.6.5/cipher/primegen.c.leak libgcrypt-1.6.5/cipher/primegen.c ---- libgcrypt-1.6.5/cipher/primegen.c.leak 2016-07-21 11:06:32.783421204 +0200 -+++ libgcrypt-1.6.5/cipher/primegen.c 2016-07-21 11:06:32.789421337 +0200 -@@ -1208,10 +1208,7 @@ _gcry_prime_group_generator (gcry_mpi_t - gcry_mpi_t prime, gcry_mpi_t *factors, - gcry_mpi_t start_g) - { -- gcry_mpi_t tmp = mpi_new (0); -- gcry_mpi_t b = mpi_new (0); -- gcry_mpi_t pmin1 = mpi_new (0); -- gcry_mpi_t g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); -+ gcry_mpi_t tmp, b, pmin1, g; - int first = 1; - int i, n; - -@@ -1224,6 +1221,11 @@ _gcry_prime_group_generator (gcry_mpi_t - if (n < 2) - return GPG_ERR_INV_ARG; - -+ tmp = mpi_new (0); -+ b = mpi_new (0); -+ pmin1 = mpi_new (0); -+ g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); -+ - /* Extra sanity check - usually disabled. */ - /* mpi_set (tmp, factors[0]); */ - /* for(i = 1; i < n; i++) */ diff --git a/libgcrypt-1.7.3-aliasing.patch b/libgcrypt-1.7.3-aliasing.patch new file mode 100644 index 0000000..5fa3b9b --- /dev/null +++ b/libgcrypt-1.7.3-aliasing.patch @@ -0,0 +1,24 @@ +diff -up libgcrypt-1.7.3/cipher/bufhelp.h.aliasing libgcrypt-1.7.3/cipher/bufhelp.h +--- libgcrypt-1.7.3/cipher/bufhelp.h.aliasing 2016-04-07 17:30:08.000000000 +0200 ++++ libgcrypt-1.7.3/cipher/bufhelp.h 2016-11-22 17:00:13.065692916 +0100 +@@ -35,6 +35,11 @@ + # define BUFHELP_FAST_UNALIGNED_ACCESS 1 + #endif + ++#if _GCRY_GCC_VERSION >= 40400 ++# pragma GCC push_options ++# pragma GCC optimize ("no-strict-aliasing") ++#endif ++ + + #ifdef BUFHELP_FAST_UNALIGNED_ACCESS + /* Define type with one-byte alignment on architectures with fast unaligned +@@ -429,4 +434,8 @@ static inline void buf_put_le64(void *_b + + #endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ + ++#if _GCRY_GCC_VERSION >= 40400 ++# pragma GCC pop_options ++#endif ++ + #endif /*GCRYPT_BUFHELP_H*/ diff --git a/libgcrypt-1.7.3-ecc-test-fix.patch b/libgcrypt-1.7.3-ecc-test-fix.patch new file mode 100644 index 0000000..229d9f1 --- /dev/null +++ b/libgcrypt-1.7.3-ecc-test-fix.patch @@ -0,0 +1,158 @@ +diff -up libgcrypt-1.7.3/tests/basic.c.eccfix libgcrypt-1.7.3/tests/basic.c +--- libgcrypt-1.7.3/tests/basic.c.eccfix 2016-04-15 09:42:06.000000000 +0200 ++++ libgcrypt-1.7.3/tests/basic.c 2016-11-22 18:43:19.732897206 +0100 +@@ -8506,6 +8506,7 @@ check_pubkey_sign_ecdsa (int n, gcry_sex + /* */ "000102030405060708090A0B0C0D0E0F#))", + 0 + }, ++#if 0 + { 256, + "(data (flags gost)\n" + " (value #00112233445566778899AABBCCDDEEFF" +@@ -8530,6 +8531,7 @@ check_pubkey_sign_ecdsa (int n, gcry_sex + /* */ "000102030405060708090A0B0C0D0E0F#))", + 0 + }, ++#endif + { 0, NULL } + }; + +@@ -9136,6 +9138,7 @@ check_pubkey (void) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } + }, ++#if 0 + { /* GOST R 34.10-2001/2012 test 256 bit. */ + GCRY_PK_ECDSA, FLAG_SIGN, + { +@@ -9187,6 +9190,7 @@ check_pubkey (void) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } + }, ++#endif + { /* secp256k1 test 256 bit. */ + GCRY_PK_ECDSA, FLAG_SIGN, + { +diff -up libgcrypt-1.7.3/tests/benchmark.c.eccfix libgcrypt-1.7.3/tests/benchmark.c +--- libgcrypt-1.7.3/tests/benchmark.c.eccfix 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/tests/benchmark.c 2016-11-22 16:21:00.109004197 +0100 +@@ -1412,8 +1412,7 @@ ecc_bench (int iterations, int print_hea + { + #if USE_ECC + gpg_error_t err; +- const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", +- "gost256", "gost512" }; ++ const char *p_sizes[] = { "224", "256", "384", "521", "Ed25519" }; + int testno; + + if (print_header) +diff -up libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix libgcrypt-1.7.3/tests/dsa-rfc6979.c +--- libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix 2016-02-18 09:38:03.000000000 +0100 ++++ libgcrypt-1.7.3/tests/dsa-rfc6979.c 2016-11-22 16:22:11.804674008 +0100 +@@ -210,16 +210,6 @@ check_dsa_rfc6979 (void) + " ))" + }, + { +- "ECDSA, 192 bits (prime field)", +- "(private-key" +- " (ecdsa" +- " (curve \"NIST P-192\")" +- " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" +- " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" +- " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" +- " ))" +- }, +- { + "ECDSA, 224 bits (prime field)", + "(private-key" + " (ecdsa" +@@ -443,89 +433,6 @@ check_dsa_rfc6979 (void) + "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1" + }, + { +- "ECDSA, 192 bits (prime field)", +- "With SHA-1, message = \"sample\"", +- "sha1", "sample", +- "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", +- "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", +- "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-224, message = \"sample\"", +- "sha224", "sample", +- "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8", +- "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5", +- "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-256, message = \"sample\"", +- "sha256", "sample", +- "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", +- "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", +- "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-384, message = \"sample\"", +- "sha384", "sample", +- "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311", +- "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5", +- "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-512, message = \"sample\"", +- "sha512", "sample", +- "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", +- "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8", +- "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-1, message = \"test\"", +- "sha1", "test", +- "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", +- "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D", +- "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-224, message = \"test\"", +- "sha224", "test", +- "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE", +- "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34", +- "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-256, message = \"test\"", +- "sha256", "test", +- "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", +- "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", +- "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-384, message = \"test\"", +- "sha384", "test", +- "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693", +- "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367", +- "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-512, message = \"test\"", +- "sha512", "test", +- "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", +- "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739", +- "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290" +- }, +- +- +- +- { + "ECDSA, 224 bits (prime field)", + "With SHA-1, message = \"sample\"", + "sha1", "sample", diff --git a/libgcrypt-1.7.3-fips-cavs.patch b/libgcrypt-1.7.3-fips-cavs.patch new file mode 100644 index 0000000..42d028e --- /dev/null +++ b/libgcrypt-1.7.3-fips-cavs.patch @@ -0,0 +1,1311 @@ +diff -up libgcrypt-1.7.3/tests/cavs_driver.pl.cavs libgcrypt-1.7.3/tests/cavs_driver.pl +--- libgcrypt-1.7.3/tests/cavs_driver.pl.cavs 2013-03-15 20:25:38.000000000 +0100 ++++ libgcrypt-1.7.3/tests/cavs_driver.pl 2016-11-22 17:29:06.067553077 +0100 +@@ -1,9 +1,11 @@ + #!/usr/bin/env perl + # +-# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $ ++# $Id: cavs_driver.pl 2124 2010-12-20 07:56:30Z smueller $ + # + # CAVS test driver (based on the OpenSSL driver) + # Written by: Stephan Müller ++# Werner Koch (libgcrypt interface) ++# Tomas Mraz (addition of DSA2) + # Copyright (c) atsec information security corporation + # + # Permission is hereby granted, free of charge, to any person obtaining a copy +@@ -85,13 +87,16 @@ + # T[CBC|CFB??|ECB|OFB]varkey + # T[CBC|CFB??|ECB|OFB]invperm + # T[CBC|CFB??|ECB|OFB]vartext ++# WARNING: TDES in CFB and OFB mode problems see below + # + # ANSI X9.31 RNG + # ANSI931_AES128MCT + # ANSI931_AES128VST + # +-# DSA ++# DSA2 + # PQGGen ++# PQGVer ++# KeyPair + # SigGen + # SigVer + # +@@ -101,6 +106,36 @@ + # RC4PltBD + # RC4REGT + # ++# ++# TDES MCT for CFB and OFB: ++# ------------------------- ++# The inner loop cannot be handled by this script. If you want to have tests ++# for these cipher types, implement your own inner loop and add it to ++# crypto_mct. ++# ++# the value $next_source in crypto_mct is NOT set by the standard implementation ++# of this script. It would need to be set as follows for these two (code take ++# from fipsdrv.c from libgcrypt - the value input at the end will contain the ++# the value for $next_source: ++# ++# ... inner loop ... ++# ... ++# get_current_iv (hd, last_iv, blocklen); ++# ... encrypt / decrypt (input is the data to be en/decrypted and output is the ++# result of operation) ... ++# if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB)) ++# memcpy (input, last_iv, blocklen); ++# else if (cipher_mode == GCRY_CIPHER_MODE_OFB) ++# memcpy (input, last_iv, blocklen); ++# else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) ++# { ++# /* Reconstruct the output vector. */ ++# int i; ++# for (i=0; i < blocklen; i++) ++# input[i] ^= output[i]; ++# } ++# ... inner loop ends ... ++# ==> now, the value of input is to be put into $next_source + + use strict; + use warnings; +@@ -226,6 +261,8 @@ my $hmac; + # Generate the P, Q, G, Seed, counter, h (value used to generate g) values + # for DSA + # $1: modulus size ++# $2: q size ++# $3: seed (might be empty string) + # return: string with the calculated values in hex format, where each value + # is separated from the previous with a \n in the following order: + # P\n +@@ -236,6 +273,19 @@ my $hmac; + # h + my $dsa_pqggen; + ++# Generate the G value from P and Q ++# for DSA ++# $1: modulus size ++# $2: q size ++# $3: P in hex form ++# $4: Q in hex form ++# return: string with the calculated values in hex format, where each value ++# is separated from the previous with a \n in the following order: ++# P\n ++# Q\n ++# G\n ++my $dsa_ggen; ++ + # + # Generate an DSA public key from the provided parameters: + # $1: Name of file to create +@@ -255,16 +305,30 @@ my $dsa_verify; + + # generate a new DSA key with the following properties: + # PEM format +-# $1 keyfile name +-# return: file created, hash with keys of P, Q, G in hex format ++# $1: modulus size ++# $2: q size ++# $3 keyfile name ++# return: file created with key, string with values of P, Q, G in hex format + my $gen_dsakey; + ++# generate a new DSA private key XY parameters in domain: ++# PEM format ++# $1: P in hex form ++# $2: Q in hex form ++# $3: G in hex form ++# return: string with values of X, Y in hex format ++my $gen_dsakey_domain; ++ + # Sign a message with DSA + # $1: data to be signed in hex form + # $2: Key file in PEM format with the private key + # return: hash of digest information in hex format with Y, R, S as keys + my $dsa_sign; + ++my $rsa_keygen; ++ ++my $rsa_keygen_kat; ++ + ################################################################ + ##### OpenSSL interface functions + ################################################################ +@@ -404,6 +468,35 @@ sub libgcrypt_rsa_derive($$$$$$$$) { + } + + ++sub libgcrypt_rsa_keygen($) { ++ my $n = shift; ++ my $sexp; ++ ++ $n = sprintf ("%u", $n); ++ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")))\n"; ++ ++ return pipe_through_program($sexp, "fipsdrv rsa-keygen"); ++} ++ ++ ++sub libgcrypt_rsa_keygen_kat($$$$) { ++ my $n = shift; ++ my $e = shift; ++ my $p = shift; ++ my $q = shift; ++ my $sexp; ++ ++ $n = sprintf ("%u", $n); ++ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" ++ . "(test-parms" ++ . "(e #$e#)" ++ . "(p #$p#)" ++ . "(q #$q#))))\n"; ++ ++ return pipe_through_program($sexp, "fipsdrv rsa-keygen-kat"); ++} ++ ++ + sub libgcrypt_rsa_sign($$$) { + my $data = shift; + my $hashalgo = shift; +@@ -500,17 +593,32 @@ sub libgcrypt_hmac($$$$) { + return pipe_through_program($msg, $program); + } + +-sub libgcrypt_dsa_pqggen($) { ++sub libgcrypt_dsa_pqggen($$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $seed = shift; ++ ++ my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; ++ return pipe_through_program($seed, $program); ++} ++ ++sub libgcrypt_dsa_ggen($$$$) { + my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ my $domain = "(domain (p #$p#)(q #$q#))"; + +- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; ++ my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; + return pipe_through_program("", $program); + } + +-sub libgcrypt_gen_dsakey($) { ++sub libgcrypt_gen_dsakey($$$) { ++ my $mod = shift; ++ my $qsize = shift; + my $file = shift; + +- my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; ++ my $program = "fipsdrv --keysize $mod --qsize $qsize --key $file dsa-gen"; + my $tmp; + my %ret; + +@@ -519,10 +627,21 @@ sub libgcrypt_gen_dsakey($) { + $tmp = pipe_through_program("", $program); + die "dsa key gen failed: file $file not created" if (! -f $file); + +- @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); ++ @ret{'P', 'Q', 'G'} = split(/\n/, $tmp); + return %ret; + } + ++sub libgcrypt_gen_dsakey_domain($$$) { ++ my $p = shift; ++ my $q = shift; ++ my $g = shift; ++ my $domain = "(domain (p #$p#)(q #$q#)(g #$g#))"; ++ ++ my $program = "fipsdrv --key '$domain' dsa-gen-key"; ++ ++ return pipe_through_program("", $program); ++} ++ + sub libgcrypt_dsa_genpubkey($$$$$) { + my $filename = shift; + my $p = shift; +@@ -1139,7 +1258,7 @@ sub hmac_kat($$$$) { + $out .= "Tlen = $tlen\n"; + $out .= "Key = $key\n"; + $out .= "Msg = $msg\n"; +- $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; ++ $out .= "Mac = " . lc(&$hmac($key, $tlen, $msg, $hashtype{$tlen})) . "\n"; + + return $out; + } +@@ -1205,7 +1324,7 @@ sub crypto_mct($$$$$$$$) { + } + my ($CO, $CI); + my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); +- $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/); ++ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/ && defined($state_cipher_des)); + my $pid = open2($CO, $CI, $cipher_imp); + + my $calc_data = $iv; # CT[j] +@@ -1213,8 +1332,8 @@ sub crypto_mct($$$$$$$$) { + my $old_old_calc_data; # CT[j-2] + my $next_source; + +- # TDES inner loop implements logic within driver +- if ($cipher =~ /des/) { ++ # TDES inner loop implements logic within driver of libgcrypt ++ if ($cipher =~ /des/ && $opt{'I'} && $opt{'I'} eq 'libgcrypt' ) { + # Need to provide a dummy IV in case of ECB mode. + my $iv_arg = (defined($iv) && $iv ne "") + ? bin2hex($iv) +@@ -1238,6 +1357,10 @@ sub crypto_mct($$$$$$$$) { + $line = <$CO>; + } else { + for (my $j = 0; $j < $iloop; ++$j) { ++ if ($cipher =~ /des-ede3-ofb/ || ++ (!$enc && $cipher =~ /des-ede3-cfb/)) { ++ die "Implementation lacks support for TDES OFB and TDES CFB in encryption mode - the problem is that we would need to extract the IV of the last round of encryption which would be the input for the next round - see comments in this script for implementation requirements"; ++ } + $old_old_calc_data = $old_calc_data; + $old_calc_data = $calc_data; + +@@ -1429,7 +1552,7 @@ sub rsa_sigver($$$$$) { + # $7 xq2 + # $8 Xq + # return: string formatted as expected by CAVS +-sub rsa_keygen($$$$$$$$) { ++sub rsa_keygen_x931($$$$$$$$) { + my $modulus = shift; + my $e = shift; + my $xp1 = shift; +@@ -1503,21 +1626,23 @@ sub rngx931($$$$) { + return $out; + } + +-# DSA PQGGen test ++# DSA PQGen test + # $1 modulus size +-# $2 number of rounds to perform the test ++# $2 q size ++# $3 number of rounds to perform the test + # return: string formatted as expected by CAVS +-sub dsa_pqggen_driver($$) { ++sub dsa_pqgen_driver($$$) { + my $mod = shift; ++ my $qsize = shift; + my $rounds = shift; + + my $out = ""; + for(my $i=0; $i<$rounds; $i++) { +- my $ret = &$dsa_pqggen($mod); ++ my $ret = &$dsa_pqggen($mod, $qsize, ""); + my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); +- die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" +- if (!defined($P) || !defined($Q) || !defined($G) || +- !defined($Seed) || !defined($c) || !defined($H)); ++ die "Return value does not contain all expected values of P, Q, Seed, c for dsa_pqggen" ++ if (!defined($P) || !defined($Q) || ++ !defined($Seed) || !defined($c)); + + # now change the counter to decimal as CAVS wants decimal + # counter value although all other is HEX +@@ -1525,15 +1650,166 @@ sub dsa_pqggen_driver($$) { + + $out .= "P = $P\n"; + $out .= "Q = $Q\n"; +- $out .= "G = $G\n"; +- $out .= "Seed = $Seed\n"; +- $out .= "c = $c\n"; +- $out .= "H = $H\n\n"; ++ $out .= "domain_parameter_seed = $Seed\n"; ++ $out .= "counter = $c\n\n"; + } + + return $out; + } + ++# DSA GGen test ++# $1 modulus size ++# $2 q size ++# $3 p in hex form ++# $4 q in hex form ++# return: string formatted as expected by CAVS ++sub dsa_ggen_driver($$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ ++ my $out = ""; ++ my $ret = &$dsa_ggen($mod, $qsize, $p, $q); ++ my ($P, $Q, $G) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of P, Q, G for dsa_ggen" ++ if (!defined($P) || !defined($Q) || !defined($G)); ++ ++ $out .= "G = $G\n\n"; ++ ++ return $out; ++} ++ ++sub hexcomp($$) { ++ my $a = lc shift; ++ my $b = lc shift; ++ ++ if (length $a < length $b) { ++ my $c = $a; ++ $a = $b; ++ $b = $a; ++ } ++ ++ while (length $b < length $a) { ++ $b = "00$b"; ++ } ++ ++ return $a eq $b; ++} ++ ++# DSA PQVer test ++# $1 modulus size ++# $2 q size ++# $3 p in hex form ++# $4 q in hex form ++# $5 seed in hex form ++# $6 c decimal counter ++# return: string formatted as expected by CAVS ++sub dsa_pqver_driver($$$$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ my $seed = shift; ++ my $c = shift; ++ ++ my $out = ""; ++ my $ret = &$dsa_pqggen($mod, $qsize, $seed); ++ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of P, Q, G, seed, c for dsa_pqggen" ++ if (!defined($P) || !defined($Q) || !defined($G) || ++ !defined($seed2) || !defined($c2)); ++ ++ $c2 = hex($c2); ++ ++ $out .= "Seed = $seed\n"; ++ $out .= "c = $c\n"; ++ ++ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($seed, $seed2) && $c == $c2) { ++ $out .= "Result = P\n\n"; ++ } ++ else { ++ $out .= "Result = F\n\n"; ++ } ++ return $out; ++} ++ ++# DSA PQGVer test ++# $1 modulus size ++# $2 q size ++# $3 p in hex form ++# $4 q in hex form ++# $5 g in hex form ++# $6 seed in hex form ++# $7 c decimal counter ++# $8 h in hex form ++# return: string formatted as expected by CAVS ++sub dsa_pqgver_driver($$$$$$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ my $g = shift; ++ my $seed = shift; ++ my $c = shift; ++ my $h = shift; ++ ++ my $out = ""; ++ my $ret = &$dsa_pqggen($mod, $qsize, $seed); ++ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of P, Q, G, seed, c, H for dsa_pqggen" ++ if (!defined($P) || !defined($Q) || !defined($G) || ++ !defined($seed2) || !defined($c2) || !defined($h2)); ++ ++ ++ ++ $out .= "Seed = $seed\n"; ++ $out .= "c = $c\n"; ++ $out .= "H = $h\n"; ++ ++ $c2 = hex($c2); ++ ++ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($G, $g) && hexcomp($seed, $seed2) && ++ $c == $c2 && hex($h) == hex($h2)) { ++ $out .= "Result = P\n\n"; ++ } ++ else { ++ $out .= "Result = F\n\n"; ++ } ++ ++ return $out; ++} ++ ++# DSA Keypair test ++# $1 modulus size ++# $2 q size ++# $3 number of rounds to perform the test ++# return: string formatted as expected by CAVS ++sub dsa_keypair_driver($$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $rounds = shift; ++ ++ my $out = ""; ++ my $tmpkeyfile = "dsa_siggen.tmp.$$"; ++ my %pqg = &$gen_dsakey($mod, $qsize, $tmpkeyfile); ++ $out .= "P = " . $pqg{'P'} . "\n"; ++ $out .= "Q = " . $pqg{'Q'} . "\n"; ++ $out .= "G = " . $pqg{'G'} . "\n\n"; ++ unlink($tmpkeyfile); ++ ++ for(my $i=0; $i<$rounds; $i++) { ++ my $ret = &$gen_dsakey_domain($pqg{'P'}, $pqg{'Q'}, $pqg{'G'}); ++ my ($X, $Y) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of X, Y for gen_dsakey_domain" ++ if (!defined($X) || !defined($Y)); ++ ++ $out .= "X = $X\n"; ++ $out .= "Y = $Y\n\n"; ++ } ++ ++ return $out; ++} + + # DSA SigGen test + # $1: Message to be signed in hex form +@@ -1598,6 +1874,53 @@ sub dsa_sigver($$$$$$$$) { + return $out; + } + ++# RSA Keygen RPP test ++# $1 modulus size ++# $2 number of rounds to perform the test ++# return: string formatted as expected by CAVS ++sub rsa_keygen_driver($$) { ++ my $mod = shift; ++ my $rounds = shift; ++ ++ my $out = ""; ++ ++ for(my $i=0; $i<$rounds; $i++) { ++ my $ret = &$rsa_keygen($mod); ++ my ($e, $p, $q, $n, $d) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of e, p, q, n, d for rsa_keygen" ++ if (!defined($e) || !defined($p) || !defined($q) || !defined($n) || !defined($d)); ++ ++ $out .= "e = $e\n"; ++ $out .= "p = $p\n"; ++ $out .= "q = $q\n"; ++ $out .= "n = $n\n"; ++ $out .= "d = $d\n\n"; ++ } ++ ++ return $out; ++} ++ ++# RSA RPP Keygen KAT test ++# $1 modulus size ++# $2 p in hex form ++# $3 q in hex form ++# return: string formatted as expected by CAVS ++sub rsa_keygen_kat_driver($$$) { ++ my $mod = shift; ++ my $p = shift; ++ my $q = shift; ++ ++ my $out = ""; ++ my $ret = &$rsa_keygen_kat($mod, $p, $q); ++ my ($Result) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of Result for rsa_keygen_kat" ++ if (!defined($Result)); ++ ++ $out .= "Result = $Result\n\n"; ++ return $out; ++} ++ ++ + ############################################################## + # Parser of input file and generator of result file + # +@@ -1658,12 +1981,18 @@ sub parse($$) { + my $klen = ""; + my $tlen = ""; + my $modulus = ""; ++ my $qsize = ""; + my $capital_n = 0; ++ my $num = 0; + my $capital_p = ""; + my $capital_q = ""; + my $capital_g = ""; + my $capital_y = ""; + my $capital_r = ""; ++ my $capital_h = ""; ++ my $c = ""; ++ my $prandom = ""; ++ my $qrandom = ""; + my $xp1 = ""; + my $xp2 = ""; + my $Xp = ""; +@@ -1700,7 +2029,7 @@ sub parse($$) { + + ##### Extract cipher + # XXX there may be more - to be added +- if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) { ++ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyGen - Random Probably Prime|KeyPair|PQGVer)/) { + if ($tmpline =~ /CBC/) { $mode="cbc"; } + elsif ($tmpline =~ /ECB/) { $mode="ecb"; } + elsif ($tmpline =~ /OFB/) { $mode="ofb"; } +@@ -1749,7 +2078,23 @@ sub parse($$) { + + if ($tt == 0) { + ##### Identify the test type +- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { ++ if ($tmpline =~ /KeyGen - Random Probably Prime Known Answer Test/) { ++ $tt = 19; ++ die "Interface function rsa_keygen_kat for RSA key generation KAT not defined for tested library" ++ if (!defined($rsa_keygen_kat)); ++ } elsif ($tmpline =~ /KeyGen - Random Probably Prime Test/) { ++ $tt = 18; ++ die "Interface function rsa_keygen for RSA key generation not defined for tested library" ++ if (!defined($rsa_keygen)); ++ } elsif ($tmpline =~ /PQGVer/) { ++ $tt = 16; ++ die "Interface function for DSA PQGVer testing not defined for tested library" ++ if (!defined($dsa_pqggen)); ++ } elsif ($tmpline =~ /KeyPair/) { ++ $tt = 14; ++ die "Interface function dsa_keygen for DSA key generation not defined for tested library" ++ if (!defined($gen_dsakey_domain)); ++ } elsif ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { + $tt = 13; + die "Interface function rsa_derive for RSA key generation not defined for tested library" + if (!defined($rsa_derive)); +@@ -1760,11 +2105,11 @@ sub parse($$) { + } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { + $tt = 11; + die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" +- if (!defined($dsa_sign) || !defined($gen_rsakey)); ++ if (!defined($dsa_sign) || !defined($gen_dsakey)); + } elsif ($tmpline =~ /PQGGen/) { + $tt = 10; + die "Interface function for DSA PQGGen testing not defined for tested library" +- if (!defined($dsa_pqggen)); ++ if (!defined($dsa_pqggen) || !defined($dsa_ggen)); + } elsif ($tmpline =~ /Hash sizes tested/) { + $tt = 9; + die "Interface function hmac for HMAC testing not defined for tested library" +@@ -1792,7 +2137,7 @@ sub parse($$) { + } elsif ($tmpline =~ /Monte|MCT|Carlo/) { + $tt = 2; + die "Interface function state_cipher for Stateful Cipher operation defined for tested library" +- if (!defined($state_cipher) || !defined($state_cipher_des)); ++ if (!defined($state_cipher) && !defined($state_cipher_des)); + } elsif ($cipher =~ /^sha/) { + $tt = 3; + die "Interface function hash for Hashing not defined for tested library" +@@ -1875,18 +2220,44 @@ sub parse($$) { + die "Msg/Seed seen twice - input file crap" if ($pt ne ""); + $pt=$2; + } +- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests ++ elsif ($line =~ /^\[A.2.1\s.*\]$/) { # found in DSA2 PQGGen request ++ $out .= $line . "\n"; # print it ++ if ($tt == 10) { ++ # now generate G from PQ ++ $tt = 15; ++ } ++ } ++ elsif ($line =~ /^\[A.2.2\s.*\]$/) { # found in DSA2 PQGVer request ++ $out .= $line . "\n"; # print it ++ if ($tt == 16) { ++ # now verify PQG ++ $tt = 17; ++ } ++ } ++ elsif ($line =~ /^\[mod\s*=\s*L=([0-9]*),\s*N=([0-9]*).*\]$/) { # found in DSA2 requests + $modulus = $1; ++ $qsize = $2; + $out .= $line . "\n\n"; # print it ++ # clear eventual PQG ++ $capital_p = ""; ++ $capital_q = ""; ++ $capital_g = ""; + # generate the private key with given bit length now + # as we have the required key length in bit + if ($tt == 11) { + $dsa_keyfile = "dsa_siggen.tmp.$$"; +- my %pqg = &$gen_dsakey($dsa_keyfile); ++ my %pqg = &$gen_dsakey($modulus, $qsize, $dsa_keyfile); + $out .= "P = " . $pqg{'P'} . "\n"; + $out .= "Q = " . $pqg{'Q'} . "\n"; +- $out .= "G = " . $pqg{'G'} . "\n"; +- } elsif ( $tt == 5 ) { ++ $out .= "G = " . $pqg{'G'} . "\n\n"; ++ } ++ } ++ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests ++ $modulus = $1; ++ $out .= $line . "\n\n"; # print it ++ # generate the private key with given bit length now ++ # as we have the required key length in bit ++ if ( $tt == 5 ) { + # XXX maybe a secure temp file name is better here + # but since it is not run on a security sensitive + # system, I hope that this is fine +@@ -1907,6 +2278,9 @@ sub parse($$) { + } + elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests + $e=$1; ++ if ($tt == 19) { ++ $out .= $line . "\n"; # print it ++ } + } + elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests + die "S seen twice - input file crap" if ($signature ne ""); +@@ -1932,11 +2306,16 @@ sub parse($$) { + if ($tlen ne ""); + $tlen=$1; + } +- elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen ++ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair + die "N seen twice - check input file" + if ($capital_n); + $capital_n = $1; + } ++ elsif ($line =~ /^Num\s*=\s*(.*)/) { #DSA PQGGen ++ die "Num seen twice - check input file" ++ if ($num); ++ $num = $1; ++ } + elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer + die "P seen twice - check input file" + if ($capital_p); +@@ -1965,6 +2344,16 @@ sub parse($$) { + if ($capital_r); + $capital_r = $1; + } ++ elsif ($line =~ /^H\s*=\s*(.*)/) { #DSA PQGVer ++ die "H seen twice - check input file" ++ if ($capital_h); ++ $capital_h = $1; ++ } ++ elsif ($line =~ /^c\s*=\s*(.*)/) { #DSA PQGVer ++ die "c seen twice - check input file" ++ if ($c); ++ $c = $1; ++ } + elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen + die "xp1 seen twice - check input file" + if ($xp1); +@@ -1995,6 +2384,22 @@ sub parse($$) { + if ($Xq); + $Xq = $1; + } ++ elsif ($line =~ /^prandom\s*=\s*(.*)/) { #RSA key gen KAT ++ die "prandom seen twice - check input file" ++ if ($prandom); ++ $prandom = $1; ++ $out .= $line . "\n"; # print it ++ } ++ elsif ($line =~ /^qrandom\s*=\s*(.*)/) { #RSA key gen KAT ++ die "qrandom seen twice - check input file" ++ if ($qrandom); ++ $qrandom = $1; ++ $out .= $line . "\n"; # print it ++ } ++ elsif ($tt == 19 && $line =~ /^ / && $qrandom eq "") { #RSA key gen KAT ++ $qrandom = "00"; ++ $out .= $line . "\n"; # print it ++ } + else { + $out .= $line . "\n"; + } +@@ -2074,11 +2479,10 @@ sub parse($$) { + } + } + elsif ($tt == 10) { +- if ($modulus ne "" && $capital_n > 0) { +- $out .= dsa_pqggen_driver($modulus, $capital_n); +- #$mod is not resetted +- $capital_n = 0; +- } ++ if ($modulus ne "" && $qsize ne "" && $num > 0) { ++ $out .= dsa_pqgen_driver($modulus, $qsize, $num); ++ $num = 0; ++ } + } + elsif ($tt == 11) { + if ($pt ne "" && $dsa_keyfile ne "") { +@@ -2124,7 +2528,7 @@ sub parse($$) { + $xq1 ne "" && + $xq2 ne "" && + $Xq ne "") { +- $out .= rsa_keygen($modulus, ++ $out .= rsa_keygen_x931($modulus, + $e, + $xp1, + $xp2, +@@ -2141,6 +2545,96 @@ sub parse($$) { + $Xq = ""; + } + } ++ elsif ($tt == 14) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_n > 0) { ++ $out .= dsa_keypair_driver($modulus, ++ $qsize, ++ $capital_n); ++ $capital_n = 0; ++ } ++ } ++ elsif ($tt == 15) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_p ne "" && ++ $capital_q ne "") { ++ $out .= dsa_ggen_driver($modulus, ++ $qsize, ++ $capital_p, ++ $capital_q); ++ $capital_p = ""; ++ $capital_q = ""; ++ $num--; ++ } ++ } ++ elsif ($tt == 16) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_p ne "" && ++ $capital_q ne "" && ++ $pt ne "" && ++ $c ne "") { ++ $out .= dsa_pqver_driver($modulus, ++ $qsize, ++ $capital_p, ++ $capital_q, ++ $pt, ++ $c); ++ $capital_p = ""; ++ $capital_q = ""; ++ $pt = ""; ++ $c = ""; ++ } ++ } ++ elsif ($tt == 17) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_p ne "" && ++ $capital_q ne "" && ++ $capital_g ne "" && ++ $pt ne "" && ++ $c ne "" && ++ $capital_h ne "") { ++ $out .= dsa_pqgver_driver($modulus, ++ $qsize, ++ $capital_p, ++ $capital_q, ++ $capital_g, ++ $pt, ++ $c, ++ $capital_h); ++ $capital_p = ""; ++ $capital_q = ""; ++ $capital_g = ""; ++ $pt = ""; ++ $c = ""; ++ $capital_h = ""; ++ } ++ } ++ elsif ($tt == 18) { ++ if ($modulus ne "" && ++ $capital_n > 0) { ++ $out .= rsa_keygen_driver($modulus, ++ $capital_n); ++ $capital_n = 0; ++ } ++ } ++ elsif ($tt == 19) { ++ if ($modulus ne "" && ++ $e ne "" && ++ $prandom ne "" && ++ $qrandom ne "") { ++ $out .= rsa_keygen_kat_driver($modulus, ++ $e, ++ $prandom, ++ $qrandom); ++ $prandom = ""; ++ $qrandom = ""; ++ $e = ""; ++ } ++ } + elsif ($tt > 0) { + die "Test case $tt not defined"; + } +@@ -2199,10 +2693,14 @@ sub main() { + $state_rng = \&libgcrypt_state_rng; + $hmac = \&libgcrypt_hmac; + $dsa_pqggen = \&libgcrypt_dsa_pqggen; ++ $dsa_ggen = \&libgcrypt_dsa_ggen; + $gen_dsakey = \&libgcrypt_gen_dsakey; ++ $gen_dsakey_domain = \&libgcrypt_gen_dsakey_domain; + $dsa_sign = \&libgcrypt_dsa_sign; + $dsa_verify = \&libgcrypt_dsa_verify; + $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; ++ $rsa_keygen = \&libgcrypt_rsa_keygen; ++ $rsa_keygen_kat = \&libgcrypt_rsa_keygen_kat; + } else { + die "Invalid interface option given"; + } +diff -up libgcrypt-1.7.3/tests/cavs_tests.sh.cavs libgcrypt-1.7.3/tests/cavs_tests.sh +--- libgcrypt-1.7.3/tests/cavs_tests.sh.cavs 2013-03-15 20:25:38.000000000 +0100 ++++ libgcrypt-1.7.3/tests/cavs_tests.sh 2016-11-22 17:29:06.067553077 +0100 +@@ -55,7 +55,7 @@ function run_one_test () { + [ -d "$respdir" ] || mkdir "$respdir" + [ -f "$rspfile" ] && rm "$rspfile" + +- if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then ++ if echo "$reqfile" | grep '/DSA.\?/req/' >/dev/null 2>/dev/null; then + dflag="-D" + fi + +diff -up libgcrypt-1.7.3/tests/fipsdrv.c.cavs libgcrypt-1.7.3/tests/fipsdrv.c +--- libgcrypt-1.7.3/tests/fipsdrv.c.cavs 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/tests/fipsdrv.c 2016-11-22 17:33:15.468330859 +0100 +@@ -892,6 +892,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) + die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); + + p = buf; ++ while (*p) ++ *p++ = tolower(*p); ++ p = buf; + if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) + p += 2; + +@@ -1765,14 +1768,14 @@ run_rsa_verify (const void *data, size_t + /* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ + static gcry_sexp_t +-dsa_gen (int keysize) ++dsa_gen (int keysize, int qsize) + { + gpg_error_t err; + gcry_sexp_t keyspec, key; + + err = gcry_sexp_build (&keyspec, NULL, +- "(genkey (dsa (nbits %d)(use-fips186-2)))", +- keysize); ++ "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)))", ++ keysize, qsize); + if (err) + die ("gcry_sexp_build failed for DSA key generation: %s\n", + gpg_strerror (err)); +@@ -1790,7 +1793,7 @@ dsa_gen (int keysize) + /* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ + static gcry_sexp_t +-dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) ++dsa_gen_with_seed (int keysize, int qsize, const void *seed, size_t seedlen) + { + gpg_error_t err; + gcry_sexp_t keyspec, key; +@@ -1799,10 +1802,11 @@ dsa_gen_with_seed (int keysize, const vo + "(genkey" + " (dsa" + " (nbits %d)" +- " (use-fips186-2)" ++ " (qbits %d)" ++ " (use-fips186)" + " (derive-parms" + " (seed %b))))", +- keysize, (int)seedlen, seed); ++ keysize, qsize, (int)seedlen, seed); + if (err) + die ("gcry_sexp_build failed for DSA key generation: %s\n", + gpg_strerror (err)); +@@ -1810,6 +1814,37 @@ dsa_gen_with_seed (int keysize, const vo + err = gcry_pk_genkey (&key, keyspec); + if (err) + die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); ++ ++ gcry_sexp_release (keyspec); ++ ++ return key; ++} ++ ++/* Generate a DSA key with specified domain parameters and return the complete ++ S-expression. */ ++static gcry_sexp_t ++dsa_gen_key (const char *domain) ++{ ++ gpg_error_t err; ++ gcry_sexp_t keyspec, key, domspec; ++ ++ err = gcry_sexp_new (&domspec, domain, strlen(domain), 0); ++ if (err) ++ die ("gcry_sexp_build failed for domain spec: %s\n", ++ gpg_strerror (err)); ++ ++ err = gcry_sexp_build (&keyspec, NULL, ++ "(genkey" ++ " (dsa" ++ " (use-fips186)" ++ " %S))", ++ domspec); ++ if (err) ++ die ("gcry_sexp_build failed for DSA key generation: %s\n", ++ gpg_strerror (err)); ++ err = gcry_pk_genkey (&key, keyspec); ++ if (err) ++ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); + + gcry_sexp_release (keyspec); + +@@ -1849,7 +1884,7 @@ ecdsa_gen_key (const char *curve) + with one parameter per line in hex format using this order: p, q, + g, seed, counter, h. */ + static void +-print_dsa_domain_parameters (gcry_sexp_t key) ++print_dsa_domain_parameters (gcry_sexp_t key, int print_misc) + { + gcry_sexp_t l1, l2; + gcry_mpi_t mpi; +@@ -1885,6 +1920,9 @@ print_dsa_domain_parameters (gcry_sexp_t + } + gcry_sexp_release (l1); + ++ if (!print_misc) ++ return; ++ + /* Extract the seed values. */ + l1 = gcry_sexp_find_token (key, "misc-key-info", 0); + if (!l1) +@@ -1976,38 +2014,106 @@ print_ecdsa_dq (gcry_sexp_t key) + } + + +-/* Generate DSA domain parameters for a modulus size of KEYSIZE. The ++/* Print just the XY private key parameters. KEY ++ is the complete key as returned by dsa_gen. We print to stdout ++ with one parameter per line in hex format using this order: x, y. */ ++static void ++print_dsa_xy (gcry_sexp_t key) ++{ ++ gcry_sexp_t l1, l2; ++ gcry_mpi_t mpi; ++ int idx; ++ ++ l1 = gcry_sexp_find_token (key, "private-key", 0); ++ if (!l1) ++ die ("private key not found in genkey result\n"); ++ ++ l2 = gcry_sexp_find_token (l1, "dsa", 0); ++ if (!l2) ++ die ("returned private key not formed as expected\n"); ++ gcry_sexp_release (l1); ++ l1 = l2; ++ ++ /* Extract the parameters from the S-expression and print them to stdout. */ ++ for (idx=0; "xy"[idx]; idx++) ++ { ++ l2 = gcry_sexp_find_token (l1, "xy"+idx, 1); ++ if (!l2) ++ die ("no %c parameter in returned public key\n", "xy"[idx]); ++ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); ++ if (!mpi) ++ die ("no value for %c parameter in returned private key\n","xy"[idx]); ++ gcry_sexp_release (l2); ++ if (standalone_mode) ++ printf ("%c = ", "XY"[idx]); ++ print_mpi_line (mpi, 1); ++ gcry_mpi_release (mpi); ++ } ++ ++ gcry_sexp_release (l1); ++} ++ ++ ++/* Generate DSA pq domain parameters for a modulus size of KEYSIZE. The + result is printed to stdout with one parameter per line in hex +- format and in this order: p, q, g, seed, counter, h. If SEED is ++ format and in this order: p, q, seed, counter. If SEED is + not NULL this seed value will be used for the generation. */ + static void +-run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) ++run_dsa_pqg_gen (int keysize, int qsize, const void *seed, size_t seedlen) + { + gcry_sexp_t key; + + if (seed) +- key = dsa_gen_with_seed (keysize, seed, seedlen); ++ key = dsa_gen_with_seed (keysize, qsize, seed, seedlen); + else +- key = dsa_gen (keysize); +- print_dsa_domain_parameters (key); ++ key = dsa_gen (keysize, qsize); ++ print_dsa_domain_parameters (key, 1); ++ gcry_sexp_release (key); ++} ++ ++ ++/* Generate DSA domain parameters for a modulus size of KEYSIZE. The ++ result is printed to stdout with one parameter per line in hex ++ format and in this order: p, q, g, seed, counter, h. If SEED is ++ not NULL this seed value will be used for the generation. */ ++static void ++run_dsa_g_gen (int keysize, int qsize, const char *domain) ++{ ++ gcry_sexp_t key; ++ ++ key = dsa_gen_key (domain); ++ print_dsa_domain_parameters (key, 0); ++ gcry_sexp_release (key); ++} ++ ++/* Generate a DSA key with specified domain parameters ++ and print the XY values. */ ++static void ++run_dsa_gen_key (const char *domain) ++{ ++ gcry_sexp_t key; ++ ++ key = dsa_gen_key (domain); ++ print_dsa_xy (key); ++ + gcry_sexp_release (key); + } + + + /* Generate a DSA key of size of KEYSIZE and write the private key to + FILENAME. Also write the parameters to stdout in the same way as +- run_dsa_pqg_gen. */ ++ run_dsa_g_gen. */ + static void +-run_dsa_gen (int keysize, const char *filename) ++run_dsa_gen (int keysize, int qsize, const char *filename) + { + gcry_sexp_t key, private_key; + FILE *fp; + +- key = dsa_gen (keysize); ++ key = dsa_gen (keysize, qsize); + private_key = gcry_sexp_find_token (key, "private-key", 0); + if (!private_key) + die ("private key not found in genkey result\n"); +- print_dsa_domain_parameters (key); ++ print_dsa_domain_parameters (key, 1); + + fp = fopen (filename, "wb"); + if (!fp) +@@ -2020,6 +2126,53 @@ run_dsa_gen (int keysize, const char *fi + } + + ++static int ++dsa_hash_from_key(gcry_sexp_t s_key) ++{ ++ gcry_sexp_t l1, l2; ++ gcry_mpi_t q; ++ unsigned int qbits; ++ ++ l1 = gcry_sexp_find_token (s_key, "public-key", 0); ++ if (!l1) ++ { ++ l1 = gcry_sexp_find_token (s_key, "private-key", 0); ++ if (!l1) ++ die ("neither private nor public key found in the loaded key\n"); ++ } ++ ++ l2 = gcry_sexp_find_token (l1, "dsa", 0); ++ if (!l2) ++ die ("public key not formed as expected - no dsa\n"); ++ gcry_sexp_release (l1); ++ l1 = l2; ++ ++ l2 = gcry_sexp_find_token (l1, "q", 0); ++ if (!l2) ++ die ("public key not formed as expected - no q\n"); ++ gcry_sexp_release (l1); ++ l1 = l2; ++ ++ q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); ++ if (!q) ++ die ("public key not formed as expected - no mpi in q\n"); ++ qbits = gcry_mpi_get_nbits(q); ++ gcry_sexp_release(l1); ++ gcry_mpi_release(q); ++ switch(qbits) ++ { ++ case 160: ++ return GCRY_MD_SHA1; ++ case 224: ++ return GCRY_MD_SHA224; ++ case 256: ++ return GCRY_MD_SHA256; ++ default: ++ die("bad number bits (%d) of q in key\n", qbits); ++ } ++ return GCRY_MD_NONE; ++} ++ + + /* Sign DATA of length DATALEN using the key taken from the S-expression + encoded KEYFILE. */ +@@ -2029,11 +2182,16 @@ run_dsa_sign (const void *data, size_t d + { + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; +- char hash[20]; ++ char hash[128]; + gcry_mpi_t tmpmpi; ++ int algo; ++ ++ s_key = read_sexp_from_file (keyfile); ++ algo = dsa_hash_from_key(s_key); + +- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); +- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); ++ gcry_md_hash_buffer (algo, hash, data, datalen); ++ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, ++ gcry_md_get_algo_dlen(algo), NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, +@@ -2044,8 +2202,6 @@ run_dsa_sign (const void *data, size_t d + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + +- s_key = read_sexp_from_file (keyfile); +- + err = gcry_pk_sign (&s_sig, s_data, s_key); + if (err) + { +@@ -2121,13 +2277,18 @@ run_dsa_verify (const void *data, size_t + { + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig; +- char hash[20]; ++ char hash[128]; + gcry_mpi_t tmpmpi; ++ int algo; + +- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); ++ s_key = read_sexp_from_file (keyfile); ++ algo = dsa_hash_from_key(s_key); ++ ++ gcry_md_hash_buffer (algo, hash, data, datalen); + /* Note that we can't simply use %b with HASH to build the + S-expression, because that might yield a negative value. */ +- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); ++ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, ++ gcry_md_get_algo_dlen(algo), NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, +@@ -2138,7 +2299,6 @@ run_dsa_verify (const void *data, size_t + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + +- s_key = read_sexp_from_file (keyfile); + s_sig = read_sexp_from_file (sigfile); + + err = gcry_pk_verify (s_sig, s_data, s_key); +@@ -2304,7 +2464,7 @@ usage (int show_help) + "MODE:\n" + " encrypt, decrypt, digest, random, hmac-sha,\n" + " rsa-{derive,gen,sign,verify},\n" +- " dsa-{pqg-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" ++ " dsa-{pq-gen,g-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" + "OPTIONS:\n" + " --verbose Print additional information\n" + " --binary Input and output is in binary form\n" +@@ -2315,6 +2475,7 @@ usage (int show_help) + " --algo NAME Use algorithm NAME\n" + " --curve NAME Select ECC curve spec NAME\n" + " --keysize N Use a keysize of N bits\n" ++ " --qize N Use a DSA q parameter size of N bits\n" + " --signature NAME Take signature from file NAME\n" + " --chunk N Read in chunks of N bytes (implies --binary)\n" + " --pkcs1 Use PKCS#1 encoding\n" +@@ -2344,6 +2505,7 @@ main (int argc, char **argv) + const char *dt_string = NULL; + const char *algo_string = NULL; + const char *keysize_string = NULL; ++ const char *qsize_string = NULL; + const char *signature_string = NULL; + FILE *input; + void *data; +@@ -2437,6 +2599,14 @@ main (int argc, char **argv) + keysize_string = *argv; + argc--; argv++; + } ++ else if (!strcmp (*argv, "--qsize")) ++ { ++ argc--; argv++; ++ if (!argc) ++ usage (0); ++ qsize_string = *argv; ++ argc--; argv++; ++ } + else if (!strcmp (*argv, "--signature")) + { + argc--; argv++; +@@ -2792,23 +2962,49 @@ main (int argc, char **argv) + } + else if (!strcmp (mode_string, "dsa-pqg-gen")) + { +- int keysize; ++ int keysize, qsize; ++ ++ keysize = keysize_string? atoi (keysize_string) : 0; ++ if (keysize < 1024 || keysize > 3072) ++ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); ++ qsize = qsize_string? atoi (qsize_string) : 0; ++ if (qsize < 160 || qsize > 256) ++ die ("invalid qsize specified; needs to be 160 .. 256\n"); ++ run_dsa_pqg_gen (keysize, qsize, datalen? data:NULL, datalen); ++ } ++ else if (!strcmp (mode_string, "dsa-g-gen")) ++ { ++ int keysize, qsize; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); +- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); ++ qsize = qsize_string? atoi (qsize_string) : 0; ++ if (qsize < 160 || qsize > 256) ++ die ("invalid qsize specified; needs to be 160 .. 256\n"); ++ if (!key_string) ++ die ("option --key containing pq domain parameters is required in this mode\n"); ++ run_dsa_g_gen (keysize, qsize, key_string); ++ } ++ else if (!strcmp (mode_string, "dsa-gen-key")) ++ { ++ if (!key_string) ++ die ("option --key containing pqg domain parameters is required in this mode\n"); ++ run_dsa_gen_key (key_string); + } + else if (!strcmp (mode_string, "dsa-gen")) + { +- int keysize; ++ int keysize, qsize; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); ++ qsize = qsize_string? atoi (qsize_string) : 0; ++ if (qsize < 160 || qsize > 256) ++ die ("invalid qsize specified; needs to be 160 .. 256\n"); + if (!key_string) + die ("option --key is required in this mode\n"); +- run_dsa_gen (keysize, key_string); ++ run_dsa_gen (keysize, qsize, key_string); + } + else if (!strcmp (mode_string, "dsa-sign")) + { diff --git a/libgcrypt-1.7.3-fips-cfgrandom.patch b/libgcrypt-1.7.3-fips-cfgrandom.patch new file mode 100644 index 0000000..c9786e4 --- /dev/null +++ b/libgcrypt-1.7.3-fips-cfgrandom.patch @@ -0,0 +1,104 @@ +diff -up libgcrypt-1.7.3/random/random-drbg.c.cfgrandom libgcrypt-1.7.3/random/random-drbg.c +--- libgcrypt-1.7.3/random/random-drbg.c.cfgrandom 2016-04-07 17:30:08.000000000 +0200 ++++ libgcrypt-1.7.3/random/random-drbg.c 2016-11-22 15:54:02.227319203 +0100 +@@ -627,8 +627,13 @@ drbg_get_entropy (drbg_state_t drbg, uns + read_cb_size = len; + read_cb_len = 0; + #if USE_RNDLINUX ++ /* First read from /etc/gcrypt/rngseed if available */ ++ _gcry_rndlinux_gather_random (drbg_read_cb, 0, len, ++ -1); ++ read_cb_len = 0; ++ /* then use /dev/urandom. */ + rc = _gcry_rndlinux_gather_random (drbg_read_cb, 0, len, +- GCRY_VERY_STRONG_RANDOM); ++ GCRY_STRONG_RANDOM); + #elif USE_RNDUNIX + rc = _gcry_rndunix_gather_random (drbg_read_cb, 0, len, + GCRY_VERY_STRONG_RANDOM); +diff -up libgcrypt-1.7.3/random/rndlinux.c.cfgrandom libgcrypt-1.7.3/random/rndlinux.c +--- libgcrypt-1.7.3/random/rndlinux.c.cfgrandom 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/random/rndlinux.c 2016-11-22 15:45:19.921141761 +0100 +@@ -40,7 +40,9 @@ + #include "g10lib.h" + #include "rand-internal.h" + +-static int open_device (const char *name, int retry); ++#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed" ++ ++static int open_device (const char *name, int retry, int fatal); + + + static int +@@ -63,7 +65,7 @@ set_cloexec_flag (int fd) + * a fatal error but retries until it is able to reopen the device. + */ + static int +-open_device (const char *name, int retry) ++open_device (const char *name, int retry, int fatal) + { + int fd; + +@@ -71,6 +73,8 @@ open_device (const char *name, int retry + _gcry_random_progress ("open_dev_random", 'X', 1, 0); + again: + fd = open (name, O_RDONLY); ++ if (fd == -1 && !fatal) ++ return fd; + if (fd == -1 && retry) + { + struct timeval tv; +@@ -115,6 +119,7 @@ _gcry_rndlinux_gather_random (void (*add + { + static int fd_urandom = -1; + static int fd_random = -1; ++ static int fd_configured = -1; + static unsigned char ever_opened; + int fd; + int n; +@@ -138,6 +143,11 @@ _gcry_rndlinux_gather_random (void (*add + close (fd_urandom); + fd_urandom = -1; + } ++ if (fd_configured != -1) ++ { ++ close (fd_configured); ++ fd_configured = -1; ++ } + return 0; + } + +@@ -165,20 +175,30 @@ _gcry_rndlinux_gather_random (void (*add + that we always require the device to be existent but want a more + graceful behaviour if the rarely needed close operation has been + used and the device needs to be re-opened later. */ ++ ++ if (level == -1) ++ { ++ if (fd_configured == -1) ++ fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0, 0 ); ++ fd = fd_configured; ++ if (fd == -1) ++ return -1; ++ } ++ + if (level >= 2) + { + if (fd_random == -1) + { +- fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1)); ++ fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1); + ever_opened |= 1; + } + fd = fd_random; + } +- else ++ else if (level != -1) + { + if (fd_urandom == -1) + { +- fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); ++ fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2), 1); + ever_opened |= 2; + } + fd = fd_urandom; diff --git a/libgcrypt-1.7.3-fips-reqs.patch b/libgcrypt-1.7.3-fips-reqs.patch new file mode 100644 index 0000000..ef7f765 --- /dev/null +++ b/libgcrypt-1.7.3-fips-reqs.patch @@ -0,0 +1,35 @@ +diff -up libgcrypt-1.7.3/src/visibility.c.fips-reqs libgcrypt-1.7.3/src/visibility.c +--- libgcrypt-1.7.3/src/visibility.c.fips-reqs 2016-03-23 12:59:34.000000000 +0100 ++++ libgcrypt-1.7.3/src/visibility.c 2016-11-22 16:29:36.992042480 +0100 +@@ -1288,6 +1288,8 @@ gcry_kdf_derive (const void *passphrase, + unsigned long iterations, + size_t keysize, void *keybuffer) + { ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); + return gpg_error (_gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, + salt, saltlen, iterations, + keysize, keybuffer)); +@@ -1343,6 +1345,13 @@ void + gcry_mpi_randomize (gcry_mpi_t w, + unsigned int nbits, enum gcry_random_level level) + { ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ fips_signal_fatal_error ("called in non-operational state"); ++ fips_noreturn (); ++ } ++ + _gcry_mpi_randomize (w, nbits, level); + } + +@@ -1368,6 +1377,8 @@ gcry_prime_generate (gcry_mpi_t *prime, + gcry_random_level_t random_level, + unsigned int flags) + { ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); + return gpg_error (_gcry_prime_generate (prime, prime_bits, factor_bits, + factors, cb_func, cb_arg, + random_level, flags)); diff --git a/libgcrypt-1.7.3-tests.patch b/libgcrypt-1.7.3-tests.patch new file mode 100644 index 0000000..f1b461c --- /dev/null +++ b/libgcrypt-1.7.3-tests.patch @@ -0,0 +1,115 @@ +diff -up libgcrypt-1.7.3/cipher/dsa.c.tests libgcrypt-1.7.3/cipher/dsa.c +--- libgcrypt-1.7.3/cipher/dsa.c.tests 2016-04-07 17:30:08.000000000 +0200 ++++ libgcrypt-1.7.3/cipher/dsa.c 2016-11-22 15:33:48.813026002 +0100 +@@ -457,11 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen); +- else +- ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, ++ else if (!domain->p || !domain->q) ++ ec = _gcry_generate_fips186_3_prime (nbits, qbits, ++ initial_seed.seed, ++ initial_seed.seedlen, + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen, NULL); ++ else ++ { ++ /* Domain parameters p and q are given; use them. */ ++ prime_p = mpi_copy (domain->p); ++ prime_q = mpi_copy (domain->q); ++ gcry_assert (mpi_get_nbits (prime_p) == nbits); ++ gcry_assert (mpi_get_nbits (prime_q) == qbits); ++ ec = 0; ++ } + sexp_release (initial_seed.sexp); + if (ec) + goto leave; +@@ -855,13 +866,12 @@ dsa_generate (const gcry_sexp_t genparms + sexp_release (l1); + sexp_release (domainsexp); + +- /* Check that all domain parameters are available. */ +- if (!domain.p || !domain.q || !domain.g) ++ /* Check that p and q domain parameters are available. */ ++ if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) + { + _gcry_mpi_release (domain.p); + _gcry_mpi_release (domain.q); + _gcry_mpi_release (domain.g); +- sexp_release (deriveparms); + return GPG_ERR_MISSING_VALUE; + } + +diff -up libgcrypt-1.7.3/cipher/rsa.c.tests libgcrypt-1.7.3/cipher/rsa.c +--- libgcrypt-1.7.3/cipher/rsa.c.tests 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/cipher/rsa.c 2016-11-22 15:25:05.426838229 +0100 +@@ -696,7 +696,7 @@ generate_x931 (RSA_secret_key *sk, unsig + + *swapped = 0; + +- if (e_value == 1) /* Alias for a secure value. */ ++ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ + e_value = 65537; + + /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ +diff -up libgcrypt-1.7.3/tests/keygen.c.tests libgcrypt-1.7.3/tests/keygen.c +--- libgcrypt-1.7.3/tests/keygen.c.tests 2016-04-07 17:30:08.000000000 +0200 ++++ libgcrypt-1.7.3/tests/keygen.c 2016-11-22 15:25:33.178484464 +0100 +@@ -257,11 +257,11 @@ check_rsa_keys (void) + + + if (verbose) +- show ("creating 512 bit RSA key with e=257\n"); ++ show ("creating 1024 bit RSA key with e=257\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" +- " (nbits 3:512)\n" ++ " (nbits 4:1024)\n" + " (rsa-use-e 3:257)\n" + " ))", 0, 1); + if (rc) +@@ -282,11 +282,11 @@ check_rsa_keys (void) + gcry_sexp_release (key); + + if (verbose) +- show ("creating 512 bit RSA key with default e\n"); ++ show ("creating 1024 bit RSA key with default e\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" +- " (nbits 3:512)\n" ++ " (nbits 4:1024)\n" + " (rsa-use-e 1:0)\n" + " ))", 0, 1); + if (rc) +@@ -366,12 +366,12 @@ check_dsa_keys (void) + } + + if (verbose) +- show ("creating 1536 bit DSA key\n"); ++ show ("creating 2048 bit DSA key\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (dsa\n" +- " (nbits 4:1536)\n" +- " (qbits 3:224)\n" ++ " (nbits 4:2048)\n" ++ " (qbits 3:256)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); +diff -up libgcrypt-1.7.3/tests/pubkey.c.tests libgcrypt-1.7.3/tests/pubkey.c +--- libgcrypt-1.7.3/tests/pubkey.c.tests 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/tests/pubkey.c 2016-11-22 18:40:23.220813982 +0100 +@@ -651,7 +651,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ + " (use-fips186)" + " (transient-key)" + " (derive-parms" +- " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", ++ " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", + 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); diff --git a/libgcrypt-1.7.3-use-poll.patch b/libgcrypt-1.7.3-use-poll.patch new file mode 100644 index 0000000..16b7164 --- /dev/null +++ b/libgcrypt-1.7.3-use-poll.patch @@ -0,0 +1,71 @@ +diff -up libgcrypt-1.7.3/random/rndlinux.c.use-poll libgcrypt-1.7.3/random/rndlinux.c +--- libgcrypt-1.7.3/random/rndlinux.c.use-poll 2016-11-22 16:05:05.114761069 +0100 ++++ libgcrypt-1.7.3/random/rndlinux.c 2016-11-22 16:16:05.373139721 +0100 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #if defined(__linux__) && defined(HAVE_SYSCALL) + # include + #endif +@@ -211,9 +212,11 @@ _gcry_rndlinux_gather_random (void (*add + return with something we will actually use 100ms. */ + while (length) + { +- fd_set rfds; +- struct timeval tv; + int rc; ++ struct pollfd pfd; ++ ++ pfd.fd = fd; ++ pfd.events = POLLIN; + + /* If we collected some bytes update the progress indicator. We + do this always and not just if the select timed out because +@@ -227,33 +230,19 @@ _gcry_rndlinux_gather_random (void (*add + any_need_entropy = 1; + } + +- /* If the system has no limit on the number of file descriptors +- and we encounter an fd which is larger than the fd_set size, +- we don't use the select at all. The select code is only used +- to emit progress messages. A better solution would be to +- fall back to poll() if available. */ +-#ifdef FD_SETSIZE +- if (fd < FD_SETSIZE) +-#endif ++ if ( !(rc=poll(&pfd, 1, delay)) ) ++ { ++ any_need_entropy = 1; ++ delay = 3000; /* Use 3 seconds henceforth. */ ++ continue; ++ } ++ else if( rc == -1 ) + { +- FD_ZERO(&rfds); +- FD_SET(fd, &rfds); +- tv.tv_sec = delay; +- tv.tv_usec = delay? 0 : 100000; +- if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) +- { +- any_need_entropy = 1; +- delay = 3; /* Use 3 seconds henceforth. */ +- continue; +- } +- else if( rc == -1 ) +- { +- log_error ("select() error: %s\n", strerror(errno)); +- if (!delay) +- delay = 1; /* Use 1 second if we encounter an error before +- we have ever blocked. */ +- continue; +- } ++ log_error ("poll() error: %s\n", strerror(errno)); ++ if (!delay) ++ delay = 1000; /* Use 1 second if we encounter an error before ++ we have ever blocked. */ ++ continue; + } + + /* If we have a modern Linux kernel and we want to read from the diff --git a/libgcrypt.spec b/libgcrypt.spec index 590cabc..cd1628a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.6.6 +Version: 1.7.3 Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -15,36 +15,29 @@ Source3: hobble-libgcrypt Source4: ecc-curves.c Source5: curves.c Source6: t-mpi-point.c +Source7: ecc-gost.c # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump Patch2: libgcrypt-1.6.2-use-fipscheck.patch -# fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen -Patch5: libgcrypt-1.6.1-tests.patch +# fix tests in the FIPS mode, allow CAVS testing of DSA keygen +Patch5: libgcrypt-1.7.3-tests.patch # add configurable source of RNG seed and seed by default # from /dev/urandom in the FIPS mode -Patch6: libgcrypt-1.6.1-fips-cfgrandom.patch +Patch6: libgcrypt-1.7.3-fips-cfgrandom.patch # update the CAVS tests -Patch7: libgcrypt-1.6.2-fips-cavs.patch -# fix for memory leaks and other errors found by Coverity scan -Patch9: libgcrypt-1.6.5-leak.patch +Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness -Patch11: libgcrypt-1.6.1-use-poll.patch +Patch11: libgcrypt-1.7.3-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC -Patch14: libgcrypt-1.6.1-ecc-test-fix.patch -# Replace the FIPS RNG with DRBG -Patch15: libgcrypt-1.6.2-drbg.patch +Patch14: libgcrypt-1.7.3-ecc-test-fix.patch # Run the FIPS mode initialization in the shared library constructor Patch18: libgcrypt-1.6.2-fips-ctor.patch -# Make it possible to run the test suite in the FIPS mode -Patch19: libgcrypt-1.6.2-fips-test.patch -# Make the FIPS RSA keygen to be FIPS 186-4 compliant -Patch20: libgcrypt-1.6.3-rsa-fips-keygen.patch -# update the selftests for new FIPS requirements -Patch22: libgcrypt-1.6.2-fips-reqs.patch +# Block some operations if in FIPS non-operational state +Patch22: libgcrypt-1.7.3-fips-reqs.patch # do not use strict aliasing for bufhelp functions -Patch23: libgcrypt-1.6.3-aliasing.patch +Patch23: libgcrypt-1.7.3-aliasing.patch # use only urandom if /dev/random cannot be opened Patch24: libgcrypt-1.6.3-urandom-only.patch @@ -86,19 +79,15 @@ applications using libgcrypt. %patch5 -p1 -b .tests %patch6 -p1 -b .cfgrandom %patch7 -p1 -b .cavs -%patch9 -p1 -b .leak %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix -%patch15 -p1 -b .drbg %patch18 -p1 -b .fips-ctor -%patch19 -p1 -b .fips-test -%patch20 -p1 -b .fips-keygen %patch22 -p1 -b .fips-reqs %patch23 -p1 -b .aliasing %patch24 -p1 -b .urandom-only -cp %{SOURCE4} cipher/ +cp %{SOURCE4} %{SOURCE7} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ %build @@ -208,6 +197,9 @@ exit 0 %license COPYING %changelog +* Wed Nov 23 2016 Tomáš Mráz 1.7.3-1 +- new upstream version 1.7.3 + * Wed Aug 17 2016 Tomáš Mráz 1.6.6-1 - new upstream version with important security fix (CVE-2016-6316) diff --git a/sources b/sources index 4a375a0..e714a44 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -67edcc4715a8c239eac70a931e49660d libgcrypt-1.6.6-hobbled.tar.xz +8ed4255c512e382eba465330c2a939dc libgcrypt-1.7.3-hobbled.tar.xz diff --git a/t-mpi-point.c b/t-mpi-point.c index 2c977c5..b1b8b2c 100644 --- a/t-mpi-point.c +++ b/t-mpi-point.c @@ -57,9 +57,21 @@ static struct const char *a, *b; /* The coefficients. */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ + const char *h; /* Cofactor. */ } test_curve[] = { { + "NIST P-224", + "0xffffffffffffffffffffffffffffffff000000000000000000000001", + "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe", + "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", + "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , + + "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", + "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", + "0x01" + }, + { "NIST P-256", "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", @@ -67,7 +79,8 @@ static struct "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "0x01" }, { "NIST P-384", @@ -83,7 +96,8 @@ static struct "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f" + "0a60b1ce1d7e819d7a431d7c90ea0e5f", + "0x01" }, { "NIST P-521", @@ -99,18 +113,20 @@ static struct "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" - "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + "0x01" }, { "Ed25519", "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "-0x01", - "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC", + "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658" + "0x6666666666666666666666666666666666666666666666666666666666666658", + "0x08" }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; /* A sample public key for NIST P-256. */ @@ -414,28 +430,18 @@ context_alloc (void) gcry_mpi_release (a); gcry_ctx_release (ctx); - p = gcry_mpi_set_ui (NULL, 0); + p = NULL; a = gcry_mpi_set_ui (NULL, 0); - err = ec_p_new (&ctx, p, a); - if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (1)\n"); - - gcry_mpi_set_ui (p, 1); - err = ec_p_new (&ctx, p, a); - if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (2)\n"); - gcry_mpi_release (p); - p = NULL; err = ec_p_new (&ctx, p, a); if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (3)\n"); + fail ("ec_p_new: bad parameter detection failed (1)\n"); gcry_mpi_release (a); a = NULL; err = ec_p_new (&ctx, p, a); if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (4)\n"); + fail ("ec_p_new: bad parameter detection failed (2)\n"); } @@ -523,6 +529,17 @@ context_param (void) show ("checking standard curves\n"); for (idx=0; test_curve[idx].desc; idx++) { + /* P-192 and Ed25519 are not supported in fips mode */ + if (gcry_fips_mode_active()) + { + if (!strcmp(test_curve[idx].desc, "NIST P-192") + || !strcmp(test_curve[idx].desc, "Ed25519")) + { + show("skipping %s in fips mode\n", test_curve[idx].desc ); + continue; + } + } + gcry_ctx_release (ctx); err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc); if (err) @@ -546,6 +563,8 @@ context_param (void) if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y, test_curve[idx].desc, ctx)) continue; + if (get_and_cmp_mpi ("h", test_curve[idx].h, test_curve[idx].desc, ctx)) + continue; } @@ -616,6 +635,10 @@ context_param (void) gcry_sexp_release (sexp); } + /* Skipping Ed25519 if in FIPS mode (it isn't supported) */ + if (gcry_fips_mode_active()) + goto cleanup; + show ("checking sample public key (Ed25519)\n"); q = hex2mpi (sample_ed25519_q); gcry_sexp_release (keyparam); @@ -703,6 +726,7 @@ context_param (void) } + cleanup: gcry_ctx_release (ctx); gcry_sexp_release (keyparam); } @@ -804,6 +828,14 @@ basic_ec_math (void) } +/* This is the same as basic_ec_math but uses more advanced + features. */ +static void +basic_ec_math_simplified (void) +{ +} + + /* Check the math used with Twisted Edwards curves. */ static void twistededwards_math (void) @@ -963,7 +995,14 @@ main (int argc, char **argv) context_alloc (); context_param (); basic_ec_math (); - twistededwards_math (); + + /* The tests are for P-192 and ed25519 which are not supported in + FIPS mode. */ + if (!gcry_fips_mode_active()) + { + basic_ec_math_simplified (); + twistededwards_math (); + } show ("All tests completed. Errors: %d\n", error_count); return error_count ? 1 : 0;