Merge branch 'master' into f21

This commit is contained in:
Tomas Mraz 2015-03-06 18:31:40 +01:00
commit 064f602690
12 changed files with 3890 additions and 239 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2
/libgcrypt-1.5.2-hobbled.tar.xz
/libgcrypt-1.5.3-hobbled.tar.xz
/libgcrypt-1.6.1-hobbled.tar.xz
/libgcrypt-1.6.2-hobbled.tar.xz
/libgcrypt-1.6.3-hobbled.tar.xz

View File

@ -889,7 +889,7 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy)
unsigned char *encpk;
unsigned int encpklen;
if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL,
if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0,
&encpk, &encpklen))
return mpi_set_opaque (NULL, encpk, encpklen*8);
}

View File

@ -1,167 +0,0 @@
Fix ARM assembly when building __PIC__
From: Jussi Kivilinna <jussi.kivilinna@iki.fi>
* cipher/camellia-arm.S (GET_DATA_POINTER): New.
(_gcry_camellia_arm_encrypt_block): Use GET_DATA_POINTER.
(_gcry_camellia_arm_decrypt_block): Ditto.
* cipher/cast5-arm.S (GET_DATA_POINTER): New.
(_gcry_cast5_arm_encrypt_block, _gcry_cast5_arm_decrypt_block)
(_gcry_cast5_arm_enc_blk2, _gcry_cast5_arm_dec_blk2): Use
GET_DATA_POINTER.
* cipher/rijndael-arm.S (GET_DATA_POINTER): New.
(_gcry_aes_arm_encrypt_block, _gcry_aes_arm_decrypt_block): Use
GET_DATA_POINTER.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
---
cipher/camellia-arm.S | 17 +++++++++++++++--
cipher/cast5-arm.S | 21 +++++++++++++++++----
cipher/rijndael-arm.S | 17 +++++++++++++++--
3 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/cipher/camellia-arm.S b/cipher/camellia-arm.S
index c30d194..cdeaf8b 100644
--- a/cipher/camellia-arm.S
+++ b/cipher/camellia-arm.S
@@ -28,6 +28,19 @@
.syntax unified
.arm
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
/* struct camellia_ctx: */
#define key_table 0
@@ -261,7 +274,7 @@ _gcry_camellia_arm_encrypt_block:
*/
push {%r1, %r4-%r11, %ip, %lr};
- ldr RTAB1, =.Lcamellia_sp1110;
+ GET_DATA_POINTER(RTAB1, .Lcamellia_sp1110, RTAB3);
mov RMASK, #0xff;
add RTAB3, RTAB1, #(2 * 4);
push {%r3};
@@ -309,7 +322,7 @@ _gcry_camellia_arm_decrypt_block:
*/
push {%r1, %r4-%r11, %ip, %lr};
- ldr RTAB1, =.Lcamellia_sp1110;
+ GET_DATA_POINTER(RTAB1, .Lcamellia_sp1110, RTAB3);
mov RMASK, #0xff;
add RTAB3, RTAB1, #(2 * 4);
mov RMASK, RMASK, lsl#4 /* byte mask */
diff --git a/cipher/cast5-arm.S b/cipher/cast5-arm.S
index ce7fa93..db96db4 100644
--- a/cipher/cast5-arm.S
+++ b/cipher/cast5-arm.S
@@ -30,6 +30,19 @@
.extern _gcry_cast5_s1to4;
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
/* structure of crypto context */
#define Km 0
#define Kr (Km + (16 * 4))
@@ -260,7 +273,7 @@ _gcry_cast5_arm_encrypt_block:
*/
push {%r1, %r4-%r11, %ip, %lr};
- ldr Rs1, =_gcry_cast5_s1to4;
+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2);
mov RMASK, #(0xff << 2);
add Rs2, Rs1, #(0x100*4);
add Rs3, Rs1, #(0x100*4*2);
@@ -306,7 +319,7 @@ _gcry_cast5_arm_decrypt_block:
*/
push {%r1, %r4-%r11, %ip, %lr};
- ldr Rs1, =_gcry_cast5_s1to4;
+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2);
mov RMASK, #(0xff << 2);
add Rs2, Rs1, #(0x100 * 4);
add Rs3, Rs1, #(0x100 * 4 * 2);
@@ -500,7 +513,7 @@ _gcry_cast5_arm_enc_blk2:
*/
push {%lr};
- ldr Rs1, =_gcry_cast5_s1to4;
+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2);
mov RMASK, #(0xff << 2);
add Rs2, Rs1, #(0x100 * 4);
@@ -631,7 +644,7 @@ _gcry_cast5_arm_dec_blk2:
* [RR0, RL0], [RR1, RL1]: dst
*/
- ldr Rs1, =_gcry_cast5_s1to4;
+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2);
mov RMASK, #(0xff << 2);
add Rs2, Rs1, #(0x100 * 4);
diff --git a/cipher/rijndael-arm.S b/cipher/rijndael-arm.S
index 22c350c..421c3b4 100644
--- a/cipher/rijndael-arm.S
+++ b/cipher/rijndael-arm.S
@@ -28,6 +28,19 @@
.syntax unified
.arm
+#ifdef __PIC__
+# define GET_DATA_POINTER(reg, name, rtmp) \
+ ldr reg, 1f; \
+ ldr rtmp, 2f; \
+ b 3f; \
+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
+ 2: .word name(GOT); \
+ 3: add reg, pc, reg; \
+ ldr reg, [reg, rtmp];
+#else
+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
+#endif
+
/* register macros */
#define CTX %r0
#define RTAB %lr
@@ -249,7 +262,7 @@ _gcry_aes_arm_encrypt_block:
2:
sub %sp, #16;
- ldr RTAB, =.LtableE0;
+ GET_DATA_POINTER(RTAB, .LtableE0, RMASK);
str %r1, [%sp, #4]; /* dst */
mov RMASK, #0xff;
@@ -503,7 +516,7 @@ _gcry_aes_arm_decrypt_block:
2:
sub %sp, #16;
- ldr RTAB, =.LtableD0;
+ GET_DATA_POINTER(RTAB, .LtableD0, RMASK);
mov RMASK, #0xff;
str %r1, [%sp, #4]; /* dst */

2697
libgcrypt-1.6.2-drbg.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_driver.pl
--- libgcrypt-1.6.1/tests/cavs_driver.pl.cavs 2013-03-15 20:25:38.000000000 +0100
+++ libgcrypt-1.6.1/tests/cavs_driver.pl 2014-02-28 14:46:16.436544639 +0100
diff -up libgcrypt-1.5.3/tests/cavs_driver.pl.cavs libgcrypt-1.5.3/tests/cavs_driver.pl
--- libgcrypt-1.5.3/tests/cavs_driver.pl.cavs 2013-05-22 18:02:55.000000000 +0200
+++ libgcrypt-1.5.3/tests/cavs_driver.pl 2014-10-21 09:38:34.250691408 +0200
@@ -1,9 +1,11 @@
#!/usr/bin/env perl
#
@ -98,7 +98,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
#
# Generate an DSA public key from the provided parameters:
# $1: Name of file to create
@@ -255,10 +305,20 @@ my $dsa_verify;
@@ -255,16 +305,30 @@ my $dsa_verify;
# generate a new DSA key with the following properties:
# PEM format
@ -121,7 +121,53 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
# Sign a message with DSA
# $1: data to be signed in hex form
# $2: Key file in PEM format with the private key
@@ -500,17 +560,32 @@ sub libgcrypt_hmac($$$$) {
# return: hash of digest information in hex format with Y, R, S as keys
my $dsa_sign;
+my $rsa_keygen;
+
+my $rsa_keygen_kat;
+
################################################################
##### OpenSSL interface functions
################################################################
@@ -404,6 +468,35 @@ sub libgcrypt_rsa_derive($$$$$$$$) {
}
+sub libgcrypt_rsa_keygen($) {
+ my $n = shift;
+ my $sexp;
+
+ $n = sprintf ("%u", $n);
+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")))\n";
+
+ return pipe_through_program($sexp, "fipsdrv rsa-keygen");
+}
+
+
+sub libgcrypt_rsa_keygen_kat($$$$) {
+ my $n = shift;
+ my $e = shift;
+ my $p = shift;
+ my $q = shift;
+ my $sexp;
+
+ $n = sprintf ("%u", $n);
+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")"
+ . "(test-parms"
+ . "(e #$e#)"
+ . "(p #$p#)"
+ . "(q #$q#))))\n";
+
+ return pipe_through_program($sexp, "fipsdrv rsa-keygen-kat");
+}
+
+
sub libgcrypt_rsa_sign($$$) {
my $data = shift;
my $hashalgo = shift;
@@ -500,17 +593,32 @@ sub libgcrypt_hmac($$$$) {
return pipe_through_program($msg, $program);
}
@ -158,7 +204,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
my $tmp;
my %ret;
@@ -519,10 +594,21 @@ sub libgcrypt_gen_dsakey($) {
@@ -519,10 +627,21 @@ sub libgcrypt_gen_dsakey($) {
$tmp = pipe_through_program("", $program);
die "dsa key gen failed: file $file not created" if (! -f $file);
@ -181,7 +227,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
sub libgcrypt_dsa_genpubkey($$$$$) {
my $filename = shift;
my $p = shift;
@@ -1139,7 +1225,7 @@ sub hmac_kat($$$$) {
@@ -1139,7 +1258,7 @@ sub hmac_kat($$$$) {
$out .= "Tlen = $tlen\n";
$out .= "Key = $key\n";
$out .= "Msg = $msg\n";
@ -190,7 +236,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
return $out;
}
@@ -1205,7 +1291,7 @@ sub crypto_mct($$$$$$$$) {
@@ -1205,7 +1324,7 @@ sub crypto_mct($$$$$$$$) {
}
my ($CO, $CI);
my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv);
@ -199,7 +245,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
my $pid = open2($CO, $CI, $cipher_imp);
my $calc_data = $iv; # CT[j]
@@ -1213,8 +1299,8 @@ sub crypto_mct($$$$$$$$) {
@@ -1213,8 +1332,8 @@ sub crypto_mct($$$$$$$$) {
my $old_old_calc_data; # CT[j-2]
my $next_source;
@ -210,7 +256,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
# Need to provide a dummy IV in case of ECB mode.
my $iv_arg = (defined($iv) && $iv ne "")
? bin2hex($iv)
@@ -1238,6 +1324,10 @@ sub crypto_mct($$$$$$$$) {
@@ -1238,6 +1357,10 @@ sub crypto_mct($$$$$$$$) {
$line = <$CO>;
} else {
for (my $j = 0; $j < $iloop; ++$j) {
@ -221,7 +267,16 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
$old_old_calc_data = $old_calc_data;
$old_calc_data = $calc_data;
@@ -1503,21 +1593,23 @@ sub rngx931($$$$) {
@@ -1429,7 +1552,7 @@ sub rsa_sigver($$$$$) {
# $7 xq2
# $8 Xq
# return: string formatted as expected by CAVS
-sub rsa_keygen($$$$$$$$) {
+sub rsa_keygen_x931($$$$$$$$) {
my $modulus = shift;
my $e = shift;
my $xp1 = shift;
@@ -1503,21 +1626,23 @@ sub rngx931($$$$) {
return $out;
}
@ -252,7 +307,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
# now change the counter to decimal as CAVS wants decimal
# counter value although all other is HEX
@@ -1525,15 +1617,166 @@ sub dsa_pqggen_driver($$) {
@@ -1525,15 +1650,166 @@ sub dsa_pqggen_driver($$) {
$out .= "P = $P\n";
$out .= "Q = $Q\n";
@ -423,7 +478,61 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
# DSA SigGen test
# $1: Message to be signed in hex form
@@ -1658,12 +1901,16 @@ sub parse($$) {
@@ -1598,6 +1874,53 @@ sub dsa_sigver($$$$$$$$) {
return $out;
}
+# RSA Keygen RPP test
+# $1 modulus size
+# $2 number of rounds to perform the test
+# return: string formatted as expected by CAVS
+sub rsa_keygen_driver($$) {
+ my $mod = shift;
+ my $rounds = shift;
+
+ my $out = "";
+
+ for(my $i=0; $i<$rounds; $i++) {
+ my $ret = &$rsa_keygen($mod);
+ my ($e, $p, $q, $n, $d) = split(/\n/, $ret);
+ die "Return value does not contain all expected values of e, p, q, n, d for rsa_keygen"
+ if (!defined($e) || !defined($p) || !defined($q) || !defined($n) || !defined($d));
+
+ $out .= "e = $e\n";
+ $out .= "p = $p\n";
+ $out .= "q = $q\n";
+ $out .= "n = $n\n";
+ $out .= "d = $d\n\n";
+ }
+
+ return $out;
+}
+
+# RSA RPP Keygen KAT test
+# $1 modulus size
+# $2 p in hex form
+# $3 q in hex form
+# return: string formatted as expected by CAVS
+sub rsa_keygen_kat_driver($$$) {
+ my $mod = shift;
+ my $p = shift;
+ my $q = shift;
+
+ my $out = "";
+ my $ret = &$rsa_keygen_kat($mod, $p, $q);
+ my ($Result) = split(/\n/, $ret);
+ die "Return value does not contain all expected values of Result for rsa_keygen_kat"
+ if (!defined($Result));
+
+ $out .= "Result = $Result\n\n";
+ return $out;
+}
+
+
##############################################################
# Parser of input file and generator of result file
#
@@ -1658,12 +1981,18 @@ sub parse($$) {
my $klen = "";
my $tlen = "";
my $modulus = "";
@ -437,24 +546,34 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
my $capital_r = "";
+ my $capital_h = "";
+ my $c = "";
+ my $prandom = "";
+ my $qrandom = "";
my $xp1 = "";
my $xp2 = "";
my $Xp = "";
@@ -1700,7 +1947,7 @@ sub parse($$) {
@@ -1700,7 +2029,7 @@ sub parse($$) {
##### Extract cipher
# XXX there may be more - to be added
- if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) {
+ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyPair|PQGVer)/) {
+ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyGen - Random Probably Prime|KeyPair|PQGVer)/) {
if ($tmpline =~ /CBC/) { $mode="cbc"; }
elsif ($tmpline =~ /ECB/) { $mode="ecb"; }
elsif ($tmpline =~ /OFB/) { $mode="ofb"; }
@@ -1749,7 +1996,15 @@ sub parse($$) {
@@ -1749,7 +2078,23 @@ sub parse($$) {
if ($tt == 0) {
##### Identify the test type
- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) {
+ if ($tmpline =~ /PQGVer/) {
+ if ($tmpline =~ /KeyGen - Random Probably Prime Known Answer Test/) {
+ $tt = 19;
+ die "Interface function rsa_keygen_kat for RSA key generation KAT not defined for tested library"
+ if (!defined($rsa_keygen_kat));
+ } elsif ($tmpline =~ /KeyGen - Random Probably Prime Test/) {
+ $tt = 18;
+ die "Interface function rsa_keygen for RSA key generation not defined for tested library"
+ if (!defined($rsa_keygen));
+ } elsif ($tmpline =~ /PQGVer/) {
+ $tt = 16;
+ die "Interface function for DSA PQGVer testing not defined for tested library"
+ if (!defined($dsa_pqggen));
@ -466,7 +585,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
$tt = 13;
die "Interface function rsa_derive for RSA key generation not defined for tested library"
if (!defined($rsa_derive));
@@ -1760,11 +2015,11 @@ sub parse($$) {
@@ -1760,11 +2105,11 @@ sub parse($$) {
} elsif ($tmpline =~ /SigGen/ && $opt{'D'}) {
$tt = 11;
die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library"
@ -480,7 +599,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
} elsif ($tmpline =~ /Hash sizes tested/) {
$tt = 9;
die "Interface function hmac for HMAC testing not defined for tested library"
@@ -1792,7 +2047,7 @@ sub parse($$) {
@@ -1792,7 +2137,7 @@ sub parse($$) {
} elsif ($tmpline =~ /Monte|MCT|Carlo/) {
$tt = 2;
die "Interface function state_cipher for Stateful Cipher operation defined for tested library"
@ -489,7 +608,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
} elsif ($cipher =~ /^sha/) {
$tt = 3;
die "Interface function hash for Hashing not defined for tested library"
@@ -1875,18 +2130,44 @@ sub parse($$) {
@@ -1875,18 +2220,44 @@ sub parse($$) {
die "Msg/Seed seen twice - input file crap" if ($pt ne "");
$pt=$2;
}
@ -538,7 +657,17 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
# XXX maybe a secure temp file name is better here
# but since it is not run on a security sensitive
# system, I hope that this is fine
@@ -1932,11 +2213,16 @@ sub parse($$) {
@@ -1907,6 +2278,9 @@ sub parse($$) {
}
elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests
$e=$1;
+ if ($tt == 19) {
+ $out .= $line . "\n"; # print it
+ }
}
elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests
die "S seen twice - input file crap" if ($signature ne "");
@@ -1932,11 +2306,16 @@ sub parse($$) {
if ($tlen ne "");
$tlen=$1;
}
@ -556,7 +685,7 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer
die "P seen twice - check input file"
if ($capital_p);
@@ -1965,6 +2251,16 @@ sub parse($$) {
@@ -1965,6 +2344,16 @@ sub parse($$) {
if ($capital_r);
$capital_r = $1;
}
@ -573,7 +702,30 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen
die "xp1 seen twice - check input file"
if ($xp1);
@@ -2074,11 +2370,10 @@ sub parse($$) {
@@ -1995,6 +2384,22 @@ sub parse($$) {
if ($Xq);
$Xq = $1;
}
+ elsif ($line =~ /^prandom\s*=\s*(.*)/) { #RSA key gen KAT
+ die "prandom seen twice - check input file"
+ if ($prandom);
+ $prandom = $1;
+ $out .= $line . "\n"; # print it
+ }
+ elsif ($line =~ /^qrandom\s*=\s*(.*)/) { #RSA key gen KAT
+ die "qrandom seen twice - check input file"
+ if ($qrandom);
+ $qrandom = $1;
+ $out .= $line . "\n"; # print it
+ }
+ elsif ($tt == 19 && $line =~ /^ / && $qrandom eq "") { #RSA key gen KAT
+ $qrandom = "00";
+ $out .= $line . "\n"; # print it
+ }
else {
$out .= $line . "\n";
}
@@ -2074,11 +2479,10 @@ sub parse($$) {
}
}
elsif ($tt == 10) {
@ -589,7 +741,16 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
}
elsif ($tt == 11) {
if ($pt ne "" && $dsa_keyfile ne "") {
@@ -2141,6 +2436,74 @@ sub parse($$) {
@@ -2124,7 +2528,7 @@ sub parse($$) {
$xq1 ne "" &&
$xq2 ne "" &&
$Xq ne "") {
- $out .= rsa_keygen($modulus,
+ $out .= rsa_keygen_x931($modulus,
$e,
$xp1,
$xp2,
@@ -2141,6 +2545,96 @@ sub parse($$) {
$Xq = "";
}
}
@ -660,11 +821,33 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
+ $c = "";
+ $capital_h = "";
+ }
+ }
+ elsif ($tt == 18) {
+ if ($modulus ne "" &&
+ $capital_n > 0) {
+ $out .= rsa_keygen_driver($modulus,
+ $capital_n);
+ $capital_n = 0;
+ }
+ }
+ elsif ($tt == 19) {
+ if ($modulus ne "" &&
+ $e ne "" &&
+ $prandom ne "" &&
+ $qrandom ne "") {
+ $out .= rsa_keygen_kat_driver($modulus,
+ $e,
+ $prandom,
+ $qrandom);
+ $prandom = "";
+ $qrandom = "";
+ $e = "";
+ }
+ }
elsif ($tt > 0) {
die "Test case $tt not defined";
}
@@ -2199,7 +2562,9 @@ sub main() {
@@ -2199,10 +2693,14 @@ sub main() {
$state_rng = \&libgcrypt_state_rng;
$hmac = \&libgcrypt_hmac;
$dsa_pqggen = \&libgcrypt_dsa_pqggen;
@ -674,9 +857,14 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr
$dsa_sign = \&libgcrypt_dsa_sign;
$dsa_verify = \&libgcrypt_dsa_verify;
$dsa_genpubkey = \&libgcrypt_dsa_genpubkey;
diff -up libgcrypt-1.6.1/tests/cavs_tests.sh.cavs libgcrypt-1.6.1/tests/cavs_tests.sh
--- libgcrypt-1.6.1/tests/cavs_tests.sh.cavs 2013-03-15 20:25:38.000000000 +0100
+++ libgcrypt-1.6.1/tests/cavs_tests.sh 2014-02-28 14:46:16.437544662 +0100
+ $rsa_keygen = \&libgcrypt_rsa_keygen;
+ $rsa_keygen_kat = \&libgcrypt_rsa_keygen_kat;
} else {
die "Invalid interface option given";
}
diff -up libgcrypt-1.5.3/tests/cavs_tests.sh.cavs libgcrypt-1.5.3/tests/cavs_tests.sh
--- libgcrypt-1.5.3/tests/cavs_tests.sh.cavs 2013-05-22 18:02:55.000000000 +0200
+++ libgcrypt-1.5.3/tests/cavs_tests.sh 2014-09-26 17:45:38.434674884 +0200
@@ -55,7 +55,7 @@ function run_one_test () {
[ -d "$respdir" ] || mkdir "$respdir"
[ -f "$rspfile" ] && rm "$rspfile"
@ -686,9 +874,9 @@ diff -up libgcrypt-1.6.1/tests/cavs_tests.sh.cavs libgcrypt-1.6.1/tests/cavs_tes
dflag="-D"
fi
diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
--- libgcrypt-1.6.1/tests/fipsdrv.c.cavs 2013-12-16 18:44:32.000000000 +0100
+++ libgcrypt-1.6.1/tests/fipsdrv.c 2014-02-28 14:46:16.437544662 +0100
diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c
--- libgcrypt-1.5.3/tests/fipsdrv.c.cavs 2013-07-25 11:10:04.000000000 +0200
+++ libgcrypt-1.5.3/tests/fipsdrv.c 2014-10-21 09:30:30.796777225 +0200
@@ -893,6 +893,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz)
die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
@ -699,7 +887,77 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
if (no_lz && p[0] == '0' && p[1] == '0' && p[2])
p += 2;
@@ -1675,14 +1678,14 @@ run_rsa_verify (const void *data, size_t
@@ -1346,6 +1349,69 @@ run_rsa_derive (const void *data, size_t
}
+/* Generate RSA key using the S-expression in (DATA,DATALEN). This
+ S-expression is used directly as input to gcry_pk_genkey. The
+ result is printed to stdout with one parameter per line in hex
+ format and in this order: e, p, q, n, d. */
+static void
+run_rsa_keygen (const void *data, size_t datalen, int test)
+{
+ gpg_error_t err;
+ gcry_sexp_t s_keyspec, s_key, s_top, l1;
+ gcry_mpi_t mpi;
+ const char *parmlist;
+ int idx;
+
+ if (!datalen)
+ err = gpg_error (GPG_ERR_NO_DATA);
+ else
+ err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
+ if (err)
+ die ("gcry_sexp_new failed for RSA key generation: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&s_key, s_keyspec);
+
+ gcry_sexp_release (s_keyspec);
+
+ if (test) {
+ if (err)
+ printf("F\n");
+ else {
+ gcry_sexp_release (s_key);
+ printf("P\n");
+ }
+ return;
+ }
+
+ if (err)
+ die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
+
+ parmlist = "epqnd";
+
+ /* Parse and print the parameters. */
+ l1 = gcry_sexp_find_token (s_key, "private-key", 0);
+ s_top = gcry_sexp_find_token (l1, "rsa", 0);
+ gcry_sexp_release (l1);
+ if (!s_top)
+ die ("private-key part not found in result\n");
+
+ for (idx=0; parmlist[idx]; idx++)
+ {
+ l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
+ mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l1);
+ if (!mpi)
+ die ("parameter %c missing in private-key\n", parmlist[idx]);
+ print_mpi_line (mpi, 1);
+ gcry_mpi_release (mpi);
+ }
+
+ gcry_sexp_release (s_top);
+ gcry_sexp_release (s_key);
+}
+
+
static size_t
compute_tag_length (size_t n)
@@ -1675,14 +1741,14 @@ run_rsa_verify (const void *data, size_t
/* Generate a DSA key of size KEYSIZE and return the complete
S-expression. */
static gcry_sexp_t
@ -717,7 +975,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
if (err)
die ("gcry_sexp_build failed for DSA key generation: %s\n",
gpg_strerror (err));
@@ -1700,7 +1703,7 @@ dsa_gen (int keysize)
@@ -1700,7 +1766,7 @@ dsa_gen (int keysize)
/* Generate a DSA key of size KEYSIZE and return the complete
S-expression. */
static gcry_sexp_t
@ -726,7 +984,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
{
gpg_error_t err;
gcry_sexp_t keyspec, key;
@@ -1709,10 +1712,11 @@ dsa_gen_with_seed (int keysize, const vo
@@ -1709,10 +1775,11 @@ dsa_gen_with_seed (int keysize, const vo
"(genkey"
" (dsa"
" (nbits %d)"
@ -740,7 +998,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
if (err)
die ("gcry_sexp_build failed for DSA key generation: %s\n",
gpg_strerror (err));
@@ -1720,6 +1724,37 @@ dsa_gen_with_seed (int keysize, const vo
@@ -1720,6 +1787,37 @@ dsa_gen_with_seed (int keysize, const vo
err = gcry_pk_genkey (&key, keyspec);
if (err)
die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
@ -778,7 +1036,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
gcry_sexp_release (keyspec);
@@ -1732,7 +1767,7 @@ dsa_gen_with_seed (int keysize, const vo
@@ -1732,7 +1830,7 @@ dsa_gen_with_seed (int keysize, const vo
with one parameter per line in hex format using this order: p, q,
g, seed, counter, h. */
static void
@ -787,7 +1045,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
{
gcry_sexp_t l1, l2;
gcry_mpi_t mpi;
@@ -1768,6 +1803,9 @@ print_dsa_domain_parameters (gcry_sexp_t
@@ -1768,6 +1866,9 @@ print_dsa_domain_parameters (gcry_sexp_t
}
gcry_sexp_release (l1);
@ -797,7 +1055,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
/* Extract the seed values. */
l1 = gcry_sexp_find_token (key, "misc-key-info", 0);
if (!l1)
@@ -1819,38 +1857,106 @@ print_dsa_domain_parameters (gcry_sexp_t
@@ -1819,38 +1920,106 @@ print_dsa_domain_parameters (gcry_sexp_t
}
@ -914,7 +1172,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
fp = fopen (filename, "wb");
if (!fp)
@@ -1863,6 +1969,53 @@ run_dsa_gen (int keysize, const char *fi
@@ -1863,6 +2032,53 @@ run_dsa_gen (int keysize, const char *fi
}
@ -968,7 +1226,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
/* Sign DATA of length DATALEN using the key taken from the S-expression
encoded KEYFILE. */
@@ -1872,11 +2025,16 @@ run_dsa_sign (const void *data, size_t d
@@ -1872,11 +2088,16 @@ run_dsa_sign (const void *data, size_t d
{
gpg_error_t err;
gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2;
@ -976,19 +1234,19 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/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 +2045,6 @@ run_dsa_sign (const void *data, size_t d
@@ -1887,8 +2108,6 @@ run_dsa_sign (const void *data, size_t d
die ("gcry_sexp_build failed for DSA data input: %s\n",
gpg_strerror (err));
@ -997,7 +1255,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
err = gcry_pk_sign (&s_sig, s_data, s_key);
if (err)
{
@@ -1964,13 +2120,18 @@ run_dsa_verify (const void *data, size_t
@@ -1964,13 +2183,18 @@ run_dsa_verify (const void *data, size_t
{
gpg_error_t err;
gcry_sexp_t s_data, s_key, s_sig;
@ -1019,7 +1277,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
if (!err)
{
err = gcry_sexp_build (&s_data, NULL,
@@ -1981,7 +2142,6 @@ run_dsa_verify (const void *data, size_t
@@ -1981,7 +2205,6 @@ run_dsa_verify (const void *data, size_t
die ("gcry_sexp_build failed for DSA data input: %s\n",
gpg_strerror (err));
@ -1027,7 +1285,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
s_sig = read_sexp_from_file (sigfile);
err = gcry_pk_verify (s_sig, s_data, s_key);
@@ -2014,7 +2174,7 @@ usage (int show_help)
@@ -2014,7 +2237,7 @@ usage (int show_help)
"Run a crypto operation using hex encoded input and output.\n"
"MODE:\n"
" encrypt, decrypt, digest, random, hmac-sha,\n"
@ -1036,7 +1294,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
"OPTIONS:\n"
" --verbose Print additional information\n"
" --binary Input and output is in binary form\n"
@@ -2024,6 +2184,7 @@ usage (int show_help)
@@ -2024,6 +2247,7 @@ usage (int show_help)
" --dt DT Use the hex encoded DT for the RNG\n"
" --algo NAME Use algorithm NAME\n"
" --keysize N Use a keysize of N bits\n"
@ -1044,7 +1302,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
" --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 +2211,7 @@ main (int argc, char **argv)
@@ -2050,6 +2274,7 @@ main (int argc, char **argv)
const char *dt_string = NULL;
const char *algo_string = NULL;
const char *keysize_string = NULL;
@ -1052,7 +1310,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
const char *signature_string = NULL;
FILE *input;
void *data;
@@ -2143,6 +2305,14 @@ main (int argc, char **argv)
@@ -2143,6 +2368,14 @@ main (int argc, char **argv)
keysize_string = *argv;
argc--; argv++;
}
@ -1067,7 +1325,26 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c
else if (!strcmp (*argv, "--signature"))
{
argc--; argv++;
@@ -2463,23 +2633,49 @@ main (int argc, char **argv)
@@ -2406,6 +2639,18 @@ main (int argc, char **argv)
die ("no data available (do not use --chunk)\n");
run_rsa_derive (data, datalen);
}
+ else if (!strcmp (mode_string, "rsa-keygen"))
+ {
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ run_rsa_keygen (data, datalen, 0);
+ }
+ else if (!strcmp (mode_string, "rsa-keygen-kat"))
+ {
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ run_rsa_keygen (data, datalen, 1);
+ }
else if (!strcmp (mode_string, "rsa-gen"))
{
int keysize;
@@ -2463,23 +2708,49 @@ main (int argc, char **argv)
}
else if (!strcmp (mode_string, "dsa-pqg-gen"))
{

View File

@ -0,0 +1,72 @@
diff -up libgcrypt-1.6.2/cipher/md.c.fips-ctor libgcrypt-1.6.2/cipher/md.c
--- libgcrypt-1.6.2/cipher/md.c.fips-ctor 2014-08-21 14:50:39.000000000 +0200
+++ libgcrypt-1.6.2/cipher/md.c 2015-02-25 13:57:21.175704866 +0100
@@ -413,11 +413,8 @@ md_enable (gcry_md_hd_t hd, int algorith
if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
{
- _gcry_inactivate_fips_mode ("MD5 used");
if (_gcry_enforced_fips_mode () )
{
- /* We should never get to here because we do not register
- MD5 in enforced fips mode. But better throw an error. */
err = GPG_ERR_DIGEST_ALGO;
}
}
diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c
--- libgcrypt-1.6.2/src/global.c.fips-ctor 2015-02-25 13:57:21.174704842 +0100
+++ libgcrypt-1.6.2/src/global.c 2015-02-25 14:03:07.066864208 +0100
@@ -132,6 +132,34 @@ global_init (void)
}
+#ifndef FIPS_MODULE_PATH
+#define FIPS_MODULE_PATH "/etc/system-fips"
+#endif
+
+void __attribute__ ((constructor)) _gcry_global_constructor (void)
+{
+ int rv;
+
+ rv = access (FIPS_MODULE_PATH, F_OK);
+ if (rv < 0 && errno != ENOENT)
+ rv = 0;
+
+ if (!rv)
+ {
+ int no_secmem_save;
+
+ /* it should be always 0 at this point but let's keep on the safe side */
+ no_secmem_save = no_secure_memory;
+ no_secure_memory = 1;
+ /* force selftests */
+ global_init ();
+ if (fips_mode ())
+ _gcry_random_initialize (1);
+ _gcry_fips_run_selftests (0);
+ no_secure_memory = no_secmem_save;
+ }
+}
+
/* This function is called by the macro fips_is_operational and makes
sure that the minimal initialization has been done. This is far
from a perfect solution and hides problems with an improper
@@ -542,8 +570,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd,
case GCRYCTL_FIPS_MODE_P:
if (fips_mode ()
- && !_gcry_is_fips_mode_inactive ()
- && !no_secure_memory)
+ && !_gcry_is_fips_mode_inactive ())
rc = GPG_ERR_GENERAL; /* Used as TRUE value */
break;
@@ -635,7 +662,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd,
break;
case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
- if (!any_init_done)
+ if (fips_mode ())
{
/* Not yet initialized at all. Set the enforced fips mode flag */
_gcry_set_preferred_rng_type (0);

View File

@ -0,0 +1,345 @@
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 #36273db1f91bdba7a0417f1223ac232999d53a7b606741076353b4d2e758"
+" 950ac705f34eb2b412d470dc4f8506d3ddd863273e673121243904bc06a4"
+" ccce2b7afe7badde116ea3a5e604530ea34e2db48f31bfca7525520285de"
+" 3db27243b2898a9a3441263f9a67bea4967b0e75baa693d5b8d8b857f24b"
+" 0f1481d1574ef6454ca63bd070cad39d55de2205e78e284dee11cfb66776"
+" 09d3e33c13f99934107bec8138f0b6349c9b506f0b91814d8994047bf03c"
+" f4b1b200488d5a8f889ec5ab3a9e443f54e7d96e47aaa1bd404631f9f034"
+" b604e12b5b7386dd3a921b71c73f32e5c3c2aba17ebfa452a0b06890d120"
+" 1279e9d7c940baf219c7a50092860d01#)"
+" (p #00fc5c6e16ce1f037bcdf7b372b28f1672b856aef7cd67d84e7d07afd543"
+" 26c335be438f4e2f1c434e6bd2b2ec526d97522bcc5c3a6bf414c674da66"
+" 381c7a3f842fe3f95ab865694606a33779b2a15b58ed5ea75f8c6566bbd1"
+" 2436e637a73d49778a8c34d86929f34d5822b05124b640a886590ab7ba5c"
+" 97da57e836da7a9cad#)"
+" (q #00ccbe7b096906ee45bf884738a8f817e5b6ba6755e3e8058bb8e253d68e"
+" ef2ce74f4af74e268d850b3fecc31cd4ebec6ac8722a257dfda67796f01e"
+" cd2857f83730756bbdd47b0c87c56c8740a5bb272c78c9745a545b0b306f"
+" 444afa71e4216166f9ee65de7c04d7fda9155b7fe27aba698672a6068d9b"
+" 9055609e4c5da9b655#)"
+" (u #00afdecbdc5268ea7b1bff7284db7f6757dae3165fd80691ed2bbe8e54a1"
+" 6f7ff950aad059e9695903d93e59ff206ee1470bd2b099ca4e83426a7684"
+" 75a1ecafd3092fec0f008d78fe773174ec6fbff85384f3a91c2e4b1f59f1"
+" 1f2000fee86569f6cab5de338087bc615b90570de4aeb1a9125abbe3834d"
+" 5a69716c0a5fa20603#)))";
+/* 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));

View File

@ -0,0 +1,18 @@
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);

View File

@ -1,7 +1,7 @@
diff -up libgcrypt-1.5.0/src/fips.c.use-fipscheck libgcrypt-1.5.0/src/fips.c
--- libgcrypt-1.5.0/src/fips.c.use-fipscheck 2011-02-04 20:17:33.000000000 +0100
+++ libgcrypt-1.5.0/src/fips.c 2011-07-20 16:17:21.000000000 +0200
@@ -570,23 +570,48 @@ run_random_selftests (void)
diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c
--- libgcrypt-1.6.2/src/fips.c.use-fipscheck 2014-08-21 14:50:39.000000000 +0200
+++ libgcrypt-1.6.2/src/fips.c 2014-09-26 11:42:20.999588282 +0200
@@ -578,23 +578,48 @@ run_random_selftests (void)
return !!err;
}
@ -55,16 +55,16 @@ diff -up libgcrypt-1.5.0/src/fips.c.use-fipscheck libgcrypt-1.5.0/src/fips.c
key, strlen (key));
if (dlen < 0)
err = gpg_error_from_syserror ();
@@ -594,7 +619,7 @@ check_binary_integrity (void)
@@ -602,7 +627,7 @@ check_binary_integrity (void)
err = gpg_error (GPG_ERR_INTERNAL);
else
{
- fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 );
+ fname = _gcry_malloc (strlen (libpath) + 1 + 5 + 1 );
- fname = xtrymalloc (strlen (info.dli_fname) + 1 + 5 + 1 );
+ fname = xtrymalloc (strlen (libpath) + 1 + 5 + 1 );
if (!fname)
err = gpg_error_from_syserror ();
else
@@ -603,7 +628,7 @@ check_binary_integrity (void)
@@ -611,7 +636,7 @@ check_binary_integrity (void)
char *p;
/* Prefix the basename with a dot. */
@ -73,10 +73,10 @@ diff -up libgcrypt-1.5.0/src/fips.c.use-fipscheck libgcrypt-1.5.0/src/fips.c
p = strrchr (fname, '/');
if (p)
p++;
diff -up libgcrypt-1.5.0/src/Makefile.in.use-fipscheck libgcrypt-1.5.0/src/Makefile.in
--- libgcrypt-1.5.0/src/Makefile.in.use-fipscheck 2011-06-29 10:58:01.000000000 +0200
+++ libgcrypt-1.5.0/src/Makefile.in 2011-07-20 16:19:33.000000000 +0200
@@ -375,7 +375,7 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \
diff -up libgcrypt-1.6.2/src/Makefile.in.use-fipscheck libgcrypt-1.6.2/src/Makefile.in
--- libgcrypt-1.6.2/src/Makefile.in.use-fipscheck 2014-08-21 15:14:08.000000000 +0200
+++ libgcrypt-1.6.2/src/Makefile.in 2014-09-26 11:41:13.271059281 +0200
@@ -449,7 +449,7 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \
../cipher/libcipher.la \
../random/librandom.la \
../mpi/libmpi.la \

View File

@ -0,0 +1,378 @@
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, q, p);
+ }
+ else
+ {
+ pqswitch = 0;
+ mpi_sub (diff, p, q);
+ }
+ 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)

View File

@ -1,6 +1,6 @@
Name: libgcrypt
Version: 1.6.1
Release: 7%{?dist}
Version: 1.6.3
Release: 1%{?dist}
URL: http://www.gnupg.org/
Source0: libgcrypt-%{version}-hobbled.tar.xz
# The original libgcrypt sources now contain potentially patented ECC
@ -17,14 +17,14 @@ Source5: curves.c
Source6: t-mpi-point.c
# make FIPS hmac compatible with fipscheck - non upstreamable
# update on soname bump
Patch2: libgcrypt-1.5.0-use-fipscheck.patch
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
# 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
# make the FIPS-186-3 DSA CAVS testable
Patch7: libgcrypt-1.6.1-fips-cavs.patch
# update the CAVS tests
Patch7: libgcrypt-1.6.2-fips-cavs.patch
# fix for memory leaks an other errors found by Coverity scan
Patch9: libgcrypt-1.6.1-leak.patch
# use poll instead of select when gathering randomness
@ -33,7 +33,16 @@ Patch11: libgcrypt-1.6.1-use-poll.patch
Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch
# fix tests to work with approved ECC
Patch14: libgcrypt-1.6.1-ecc-test-fix.patch
Patch15: libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch
# Replace the FIPS RNG with DRBG
Patch15: libgcrypt-1.6.2-drbg.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
%define gcrylibdir %{_libdir}
@ -77,7 +86,11 @@ applications using libgcrypt.
%patch11 -p1 -b .use-poll
%patch13 -p1 -b .gccopt
%patch14 -p1 -b .eccfix
%patch15 -p1 -b .pic
%patch15 -p1 -b .drbg
%patch18 -p1 -b .fips-ctor
%patch19 -p1 -b .fips-test
%patch20 -p1 -b .fips-keygen
%patch22 -p1 -b .fips-reqs
cp %{SOURCE4} cipher/
cp %{SOURCE5} %{SOURCE6} tests/
@ -188,6 +201,22 @@ exit 0
%license COPYING
%changelog
* Fri Mar 6 2015 Tomáš Mráz <tmraz@redhat.com> 1.6.3-1
- new upstream version
* Wed Feb 25 2015 Tomáš Mráz <tmraz@redhat.com> 1.6.2-4
- do not initialize secure memory during the selftest (#1195850)
* Sat Feb 21 2015 Till Maas <opensource@till.name> - 1.6.2-3
- Rebuilt for Fedora 23 Change
https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code
* Wed Jan 14 2015 Tomáš Mráz <tmraz@redhat.com> 1.6.2-2
- fix buildability of programs using gcrypt.h with -ansi (#1182200)
* Mon Dec 8 2014 Tomáš Mráz <tmraz@redhat.com> 1.6.2-1
- new upstream version
* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.6.1-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild

View File

@ -1 +1 @@
3f1076b38a407f4775adcf6e9bf43893 libgcrypt-1.6.1-hobbled.tar.xz
cbb7aa4b8c4c63f24e954fbf00e16335 libgcrypt-1.6.3-hobbled.tar.xz