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.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-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.6.2-fips-cavs.patch b/libgcrypt-1.7.3-fips-cavs.patch
similarity index 89%
rename from libgcrypt-1.6.2-fips-cavs.patch
rename to libgcrypt-1.7.3-fips-cavs.patch
index 52067b0..42d028e 100644
--- a/libgcrypt-1.6.2-fips-cavs.patch
+++ b/libgcrypt-1.7.3-fips-cavs.patch
@@ -1,6 +1,6 @@
-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
+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
#
@@ -862,9 +862,9 @@ diff -up libgcrypt-1.5.3/tests/cavs_driver.pl.cavs libgcrypt-1.5.3/tests/cavs_dr
} 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
+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"
@@ -874,10 +874,10 @@ diff -up libgcrypt-1.5.3/tests/cavs_tests.sh.cavs libgcrypt-1.5.3/tests/cavs_tes
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)
+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;
@@ -887,77 +887,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
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
+@@ -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
@@ -975,7 +905,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
if (err)
die ("gcry_sexp_build failed for DSA key generation: %s\n",
gpg_strerror (err));
-@@ -1700,7 +1766,7 @@ dsa_gen (int keysize)
+@@ -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
@@ -984,7 +914,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
{
gpg_error_t err;
gcry_sexp_t keyspec, key;
-@@ -1709,10 +1775,11 @@ dsa_gen_with_seed (int keysize, const vo
+@@ -1799,10 +1802,11 @@ dsa_gen_with_seed (int keysize, const vo
"(genkey"
" (dsa"
" (nbits %d)"
@@ -998,7 +928,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
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
+@@ -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));
@@ -1036,7 +966,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
gcry_sexp_release (keyspec);
-@@ -1732,7 +1830,7 @@ dsa_gen_with_seed (int keysize, const vo
+@@ -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
@@ -1045,7 +975,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
{
gcry_sexp_t l1, l2;
gcry_mpi_t mpi;
-@@ -1768,6 +1866,9 @@ print_dsa_domain_parameters (gcry_sexp_t
+@@ -1885,6 +1920,9 @@ print_dsa_domain_parameters (gcry_sexp_t
}
gcry_sexp_release (l1);
@@ -1055,7 +985,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
/* 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
+@@ -1976,38 +2014,106 @@ print_ecdsa_dq (gcry_sexp_t key)
}
@@ -1172,7 +1102,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
fp = fopen (filename, "wb");
if (!fp)
-@@ -1863,6 +2032,53 @@ run_dsa_gen (int keysize, const char *fi
+@@ -2020,6 +2126,53 @@ run_dsa_gen (int keysize, const char *fi
}
@@ -1226,7 +1156,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
/* 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
+@@ -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;
@@ -1234,19 +1164,19 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
+ 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);
-+ 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
+@@ -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));
@@ -1255,7 +1185,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
err = gcry_pk_sign (&s_sig, s_data, s_key);
if (err)
{
-@@ -1964,13 +2183,18 @@ run_dsa_verify (const void *data, size_t
+@@ -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;
@@ -1263,11 +1193,11 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
+ 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);
++ 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. */
@@ -1277,7 +1207,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
if (!err)
{
err = gcry_sexp_build (&s_data, NULL,
-@@ -1981,7 +2205,6 @@ run_dsa_verify (const void *data, size_t
+@@ -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));
@@ -1285,24 +1215,24 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
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"
+@@ -2304,7 +2464,7 @@ usage (int show_help)
"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"
+ " 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"
-@@ -2024,6 +2247,7 @@ usage (int show_help)
- " --dt DT Use the hex encoded DT for the RNG\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"
-@@ -2050,6 +2274,7 @@ main (int argc, char **argv)
+@@ -2344,6 +2505,7 @@ main (int argc, char **argv)
const char *dt_string = NULL;
const char *algo_string = NULL;
const char *keysize_string = NULL;
@@ -1310,7 +1240,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
const char *signature_string = NULL;
FILE *input;
void *data;
-@@ -2143,6 +2368,14 @@ main (int argc, char **argv)
+@@ -2437,6 +2599,14 @@ main (int argc, char **argv)
keysize_string = *argv;
argc--; argv++;
}
@@ -1325,36 +1255,16 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
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)
+@@ -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");
-- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen);
++
++ 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");
@@ -1363,10 +1273,11 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
+ 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");
+
+ 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");
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.6.1-use-poll.patch b/libgcrypt-1.7.3-use-poll.patch
similarity index 77%
rename from libgcrypt-1.6.1-use-poll.patch
rename to libgcrypt-1.7.3-use-poll.patch
index 2fcaebf..16b7164 100644
--- a/libgcrypt-1.6.1-use-poll.patch
+++ b/libgcrypt-1.7.3-use-poll.patch
@@ -1,15 +1,15 @@
-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
+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
- #include "types.h"
- #include "g10lib.h"
- #include "rand-internal.h"
-@@ -199,9 +200,11 @@ _gcry_rndlinux_gather_random (void (*add
+ #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)
{
@@ -23,7 +23,7 @@ diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndli
/* 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
+@@ -227,33 +230,19 @@ _gcry_rndlinux_gather_random (void (*add
any_need_entropy = 1;
}
@@ -35,7 +35,14 @@ diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndli
-#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;
@@ -54,13 +61,6 @@ diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndli
- 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
@@ -68,4 +68,4 @@ diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndli
+ continue;
}
- do
+ /* 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,8 +57,20 @@ 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",
@@ -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");
-
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;