From 725ec59b573f3d0b23747b3131612e6b0d857a8c9cd40d3e8d849b087d4b4546 Mon Sep 17 00:00:00 2001 From: Pedro Monreal Gonzalez Date: Fri, 25 Nov 2022 14:23:58 +0000 Subject: [PATCH 1/2] Accepting request 1038172 from home:pmonrealgonzalez:branches:devel:libraries:c_c++ - Update to 1.10.1: * Bug fixes: - Fix minor memory leaks in FIPS mode. - Build fixes for MUSL libc. * Other: - More portable integrity check in FIPS mode. - Add X9.62 OIDs to sha256 and sha512 modules. * Add the hardware optimizations config file hwf.deny to the /etc/gcrypt/ directory. This file can be used to globally disable the use of hardware based optimizations. * Remove not needed separate_hmac256_binary hmac256 package - Update to 1.10.0: * New and extended interfaces: - New control codes to check for FIPS 140-3 approved algorithms. - New control code to switch into non-FIPS mode. - New cipher modes SIV and GCM-SIV as specified by RFC-5297. - Extended cipher mode AESWRAP with padding as specified by RFC-5649. - New set of KDF functions. - New KDF modes Argon2 and Balloon. - New functions for combining hashing and signing/verification. * Performance: - Improved support for PowerPC architectures. - Improved ECC performance on zSeries/s390x by using accelerated scalar multiplication. - Many more assembler performance improvements for several architectures. * Bug fixes: - Fix Elgamal encryption for other implementations. OBS-URL: https://build.opensuse.org/request/show/1038172 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libgcrypt?expand=0&rev=160 --- cavs-test.sh | 61 - cavs_driver.pl | 3072 ------------ drbg_test.patch | 1371 ------ hwf.deny | 35 + ...ibgcrypt-1.10.0-allow_FSM_same_state.patch | 8 +- ...libgcrypt-1.10.0-out-of-core-handler.patch | 8 +- libgcrypt-1.10.0-use-fipscheck.patch | 114 + libgcrypt-1.10.1.tar.bz2 | 3 + libgcrypt-1.10.1.tar.bz2.sig | Bin 0 -> 238 bytes ...pt-1.4.1-rijndael_no_strict_aliasing.patch | 17 - ...t-1.5.0-LIBGCRYPT_FORCE_FIPS_MODE-env.diff | 27 - libgcrypt-1.6.1-fips-cavs.patch | 1126 ----- libgcrypt-1.6.1-use-fipscheck.patch | 81 - libgcrypt-1.8.3-fips-ctor.patch | 266 -- libgcrypt-1.8.4-fips-keygen.patch | 66 - ...1.8.4-fips_ctor_skip_integrity_check.patch | 32 - libgcrypt-1.8.4-getrandom.patch | 124 - libgcrypt-1.8.4-use_xfree.patch | 39 - libgcrypt-1.9.4.tar.bz2 | 3 - libgcrypt-1.9.4.tar.bz2.sig | Bin 119 -> 0 bytes libgcrypt-FIPS-GMAC_AES-benckmark.patch | 13 - libgcrypt-FIPS-HMAC-short-keylen.patch | 203 - ...FIPS-RSA-DSA-ECDSA-hashing-operation.patch | 245 - libgcrypt-FIPS-RSA-keylen-tests.patch | 585 --- libgcrypt-FIPS-RSA-keylen.patch | 250 - ...patch => libgcrypt-FIPS-SLI-hash-mac.patch | 70 +- ... => libgcrypt-FIPS-SLI-kdf-leylength.patch | 16 +- libgcrypt-FIPS-SLI-pk.patch | 57 +- libgcrypt-FIPS-Zeroize-hmac.patch | 35 - libgcrypt-FIPS-disable-3DES.patch | 52 - libgcrypt-FIPS-disable-DSA.patch | 44 - libgcrypt-FIPS-fix-gcry_mpi_sub_ui.patch | 230 - libgcrypt-FIPS-fix-regression-tests.patch | 448 -- libgcrypt-FIPS-hw-optimizations.patch | 31 - libgcrypt-FIPS-module-version.patch | 89 - libgcrypt-FIPS-rndjent_poll.patch | 18 +- libgcrypt-FIPS-service-indicators.patch | 375 -- ...ypt-FIPS-verify-unsupported-KDF-test.patch | 68 - libgcrypt-PCT-DSA.patch | 118 - libgcrypt-PCT-ECC.patch | 342 -- libgcrypt-PCT-RSA.patch | 123 - ...-Restore-self-tests-from-constructor.patch | 16 - libgcrypt-dsa-rfc6979-test-fix.patch | 124 - libgcrypt-ecc-ecdsa-no-blinding.patch | 82 - libgcrypt-fips_selftest_trigger_file.patch | 40 - ...ypt-fipsdrv-enable-algo-for-dsa-sign.patch | 65 - ...t-fipsdrv-enable-algo-for-dsa-verify.patch | 64 - libgcrypt-fix-rng.patch | 24 - libgcrypt-fix-tests-fipsmode.patch | 177 - libgcrypt-global_init-constructor.patch | 254 - libgcrypt-indicate-shake.patch | 13 - ...-invoke-global_init-from-constructor.patch | 14 - libgcrypt-jitterentropy-3.3.0.patch | 4168 ----------------- libgcrypt-jitterentropy-3.4.0.patch | 70 +- libgcrypt-pthread-in-t-lock-test.patch | 13 - libgcrypt-random_selftests-testentropy.patch | 15 - libgcrypt-rsa-no-blinding.patch | 92 - libgcrypt.changes | 135 + libgcrypt.keyring | 145 +- libgcrypt.spec | 211 +- 60 files changed, 547 insertions(+), 15040 deletions(-) delete mode 100644 cavs-test.sh delete mode 100644 cavs_driver.pl delete mode 100644 drbg_test.patch create mode 100644 hwf.deny rename libgcrypt-1.8.4-allow_FSM_same_state.patch => libgcrypt-1.10.0-allow_FSM_same_state.patch (58%) rename libgcrypt-out-of-core-handler.patch => libgcrypt-1.10.0-out-of-core-handler.patch (52%) create mode 100644 libgcrypt-1.10.0-use-fipscheck.patch create mode 100644 libgcrypt-1.10.1.tar.bz2 create mode 100644 libgcrypt-1.10.1.tar.bz2.sig delete mode 100644 libgcrypt-1.4.1-rijndael_no_strict_aliasing.patch delete mode 100644 libgcrypt-1.5.0-LIBGCRYPT_FORCE_FIPS_MODE-env.diff delete mode 100644 libgcrypt-1.6.1-fips-cavs.patch delete mode 100644 libgcrypt-1.6.1-use-fipscheck.patch delete mode 100644 libgcrypt-1.8.3-fips-ctor.patch delete mode 100644 libgcrypt-1.8.4-fips-keygen.patch delete mode 100644 libgcrypt-1.8.4-fips_ctor_skip_integrity_check.patch delete mode 100644 libgcrypt-1.8.4-getrandom.patch delete mode 100644 libgcrypt-1.8.4-use_xfree.patch delete mode 100644 libgcrypt-1.9.4.tar.bz2 delete mode 100644 libgcrypt-1.9.4.tar.bz2.sig delete mode 100644 libgcrypt-FIPS-GMAC_AES-benckmark.patch delete mode 100644 libgcrypt-FIPS-HMAC-short-keylen.patch delete mode 100644 libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch delete mode 100644 libgcrypt-FIPS-RSA-keylen-tests.patch delete mode 100644 libgcrypt-FIPS-RSA-keylen.patch rename libgcrypt_indicators_changes.patch => libgcrypt-FIPS-SLI-hash-mac.patch (80%) rename libgcrypt-FIPS-kdf-leylength.patch => libgcrypt-FIPS-SLI-kdf-leylength.patch (80%) delete mode 100644 libgcrypt-FIPS-Zeroize-hmac.patch delete mode 100644 libgcrypt-FIPS-disable-3DES.patch delete mode 100644 libgcrypt-FIPS-disable-DSA.patch delete mode 100644 libgcrypt-FIPS-fix-gcry_mpi_sub_ui.patch delete mode 100644 libgcrypt-FIPS-fix-regression-tests.patch delete mode 100644 libgcrypt-FIPS-hw-optimizations.patch delete mode 100644 libgcrypt-FIPS-module-version.patch delete mode 100644 libgcrypt-FIPS-service-indicators.patch delete mode 100644 libgcrypt-FIPS-verify-unsupported-KDF-test.patch delete mode 100644 libgcrypt-PCT-DSA.patch delete mode 100644 libgcrypt-PCT-ECC.patch delete mode 100644 libgcrypt-PCT-RSA.patch delete mode 100644 libgcrypt-Restore-self-tests-from-constructor.patch delete mode 100644 libgcrypt-dsa-rfc6979-test-fix.patch delete mode 100644 libgcrypt-ecc-ecdsa-no-blinding.patch delete mode 100644 libgcrypt-fips_selftest_trigger_file.patch delete mode 100644 libgcrypt-fipsdrv-enable-algo-for-dsa-sign.patch delete mode 100644 libgcrypt-fipsdrv-enable-algo-for-dsa-verify.patch delete mode 100644 libgcrypt-fix-rng.patch delete mode 100644 libgcrypt-fix-tests-fipsmode.patch delete mode 100644 libgcrypt-global_init-constructor.patch delete mode 100644 libgcrypt-indicate-shake.patch delete mode 100644 libgcrypt-invoke-global_init-from-constructor.patch delete mode 100644 libgcrypt-jitterentropy-3.3.0.patch delete mode 100644 libgcrypt-pthread-in-t-lock-test.patch delete mode 100644 libgcrypt-random_selftests-testentropy.patch delete mode 100644 libgcrypt-rsa-no-blinding.patch diff --git a/cavs-test.sh b/cavs-test.sh deleted file mode 100644 index c62bbf7..0000000 --- a/cavs-test.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -# -# This is the driver script around the actual FIPS testing -# Written by: Stephan Müller -# (c) atsec information security corporation - -# The easiest way to perform the cipher compliance testing -# is the following: -# -# 1. patch/compile/copy the openssl binary with the patch if necessary -# (old versions hang when running the MC test if unpatched) -# -# 2. unpack the test vector ZIP file to a local dir -# -# 3. set PATH in a way that cavs_driver.pl is found -# -# 4. go to the local dir where you unzipped the test vector archive and execute -# $0 -# -# 5. send atsec the prepared CAVS_results-*.zip archive found in the same dir - -DATE=$(date +%Y%m%d) -ARCH=$(uname -m) -PATH=$PATH:$(pwd) - -# test interface to be used -# can be overridden by passing an argument to this script -# possible values are: -# openssl OpenSSL (default) -# libgcrypt Libgcrypt -# cryptoapi Kernel -INTERFACE="libgcrypt" - -if [ "$1" == "-I" -a -n "$2" ]; then - INTERFACE="$2" -fi - -for i in $(find ./ -name "*.req"); -do -( - cd $(dirname $i) || exit 1 - - # We have to see whether we check on DSA based on path name - echo $(dirname $i) | if [ ! $(grep -v DSA) ]; then - /usr/lib/libgcrypt/cavs_driver.pl -I $INTERFACE -D $(basename $i) - else - /usr/lib/libgcrypt/cavs_driver.pl -I $INTERFACE $(basename $i) - fi - - - # for CAVS, we have path/req/ - # and want to have the responses in path/resp/*.rsp - if [ $(basename $(dirname $i)) = "req" ]; then - mkdir ../resp > /dev/null 2>&1 - outfile="$(basename $i .req).rsp" - mv "$outfile" ../resp/ - fi -) & -done -wait -zip -r CAVS_results-$ARCH-$DATE.zip $(find ./ -name "*.rsp") diff --git a/cavs_driver.pl b/cavs_driver.pl deleted file mode 100644 index 51c8b78..0000000 --- a/cavs_driver.pl +++ /dev/null @@ -1,3072 +0,0 @@ -#!/usr/bin/perl -# -# $Id: cavs_driver.pl 3235 2014-04-01 06:24:16Z smueller $ -# -# CAVS test driver (based on the OpenSSL driver) -# Written by: Stephan Müller -# Werner Koch (libgcrypt interface) -# Tomas Mraz (addition of DSA2) -# Copyright (c) atsec information security corporation -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# NO WARRANTY -# -# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -# REPAIR OR CORRECTION. -# -# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGES. -# -# -# test execution instruction: -# 1. get the request files from the lab -# 2. call each request file from 1. with this program: -# $0 .rep -# 3. send the resulting file .rsp to the lab -# -# -# Test should be easily adoptable to other implementations -# See the first functions for this task -# -# Following tests are covered (others may also be covered -# but have not been tested) -# -# AES -# [CBC|CFB128|ECB|OFB]GFSbox[128|192|256] -# [CBC|CFB128|ECB|OFB]MCT[128|192|256] -# [CBC|CFB128|ECB|OFB]VarKey[128|192|256] -# [CBC|CFB128|ECB|OFB]KeySbox[128|192|256] -# [CBC|CFB128|ECB|OFB]MMT[128|192|256] -# [CBC|CFB128|ECB|OFB]VarTxt[128|192|256] -# -# RSA -# SigGen[15|RSA] -# SigVer15 -# (SigVerRSA is not applicable for OpenSSL as X9.31 padding -# is not done through openssl dgst) -# KeyGen RSA X9.31 -# -# SHA -# SHA[1|224|256|384|512]ShortMsg -# SHA[1|224|256|384|512]LongMsg -# SHA[1|224|256|384|512]Monte -# -# HMAC (SHA - caveat: we only support hash output equal to the block size of -# of the hash - we do not support truncation of the hash; to support -# that, we first need to decipher the HMAC.req file - see hmac_kat() ) -# HMAC -# -# TDES -# T[CBC|CFB??|ECB|OFB]Monte[1|2|3] -# T[CBC|CFB??|ECB|OFB]permop -# T[CBC|CFB??|ECB|OFB]MMT[1|2|3] -# T[CBC|CFB??|ECB|OFB]subtab -# T[CBC|CFB??|ECB|OFB]varkey -# T[CBC|CFB??|ECB|OFB]invperm -# T[CBC|CFB??|ECB|OFB]vartext -# WARNING: TDES in CFB and OFB mode problems see below -# -# ANSI X9.31 RNG -# ANSI931_AES128MCT -# ANSI931_AES128VST -# -# DSA2 -# PQGGen -# PQGVer -# KeyPair -# SigGen -# SigVer -# -# DRBG: -# CTR DRBG -# Hash DRBG -# HMAC DRBG -# with and w/o PR -# -# RC4 (atsec developed tests) -# RC4KeyBD -# RC4MCT -# RC4PltBD -# RC4REGT -# -# -# TDES MCT for CFB and OFB: -# ------------------------- -# The inner loop cannot be handled by this script. If you want to have tests -# for these cipher types, implement your own inner loop and add it to -# crypto_mct. -# -# the value $next_source in crypto_mct is NOT set by the standard implementation -# of this script. It would need to be set as follows for these two (code take -# from fipsdrv.c from libgcrypt - the value input at the end will contain the -# the value for $next_source: -# -# ... inner loop ... -# ... -# get_current_iv (hd, last_iv, blocklen); -# ... encrypt / decrypt (input is the data to be en/decrypted and output is the -# result of operation) ... -# if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB)) -# memcpy (input, last_iv, blocklen); -# else if (cipher_mode == GCRY_CIPHER_MODE_OFB) -# memcpy (input, last_iv, blocklen); -# else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) -# { -# /* Reconstruct the output vector. */ -# int i; -# for (i=0; i < blocklen; i++) -# input[i] ^= output[i]; -# } -# ... inner loop ends ... -# ==> now, the value of input is to be put into $next_source - -use strict; -use warnings; -use IPC::Open2; -use Getopt::Std; -use MIME::Base64; - -use Math::BigInt; - -# Contains the command line options -my %opt; - -################################################################# -##### Central interface functions to the external ciphers ####### -################################################################# -# Only these interface routines should be changed in case of -# porting to a new cipher library -# -# For porting to a new library, create implementation of these functions -# and then add pointers to the respective implementation of each -# function to the given variables. - -# common encryption/decryption routine -# $1 key in hex form (please note for 3DES: even when ede3 for three -# independent ciphers is given with the cipher specification, we hand in -# either one key for k1 = k2 = k3, two keys which are concatinated for -# k1 = k3, k2 independent, or three keys which are concatinated for -# k1, k2, k3 independent) -# $2 iv in hex form -# $3 cipher - the cipher string is defined as specified in the openssl -# enc(1ssl) specification for the option "-ciphername" -# (e.g. aes-128-cbc or des-ede3-cbc) -# $4 encrypt=1/decrypt=0 -# $5 de/encrypted data in hex form -# return en/decrypted data in hex form -my $encdec; - -# -# Derive an RSA key from the given X9.31 parameters. -# $1: modulus size -# $2: E in hex form -# $3: Xp1 in hex form -# $4: Xp2 in hex form -# $5: Xp in hex form -# $6: Xq1 in hex form -# $7: Xq2 in hex form -# $8: Xq in hex form -# return: string with the calculated values in hex format, where each value -# is separated from the previous with a \n in the following order: -# P\n -# Q\n -# N\n -# D\n -my $rsa_derive; - -# Sign a message with RSA -# $1: data to be signed in hex form -# $2: Hash algo -# $3: Key file in PEM format with the private key -# return: digest in hex format -my $rsa_sign; - -# Verify a message with RSA -# $1: data to be verified in hex form -# $2: hash algo -# $3: file holding the public RSA key in PEM format -# $4: file holding the signature in binary form -# return: 1 == verified / 0 == not verified -my $rsa_verify; - -# generate a new private RSA key with the following properties: -# exponent is 65537 -# PEM format -# $1 key size in bit -# $2 keyfile name -# return: nothing, but file created -my $gen_rsakey; - -# Creating a hash -# $1: Plaintext in hex form -# $2: hash type in the form documented in openssl's dgst(1ssl) - e.g. -# sha1, sha224, sha256, sha384, sha512 -# return: hash in hex form -my $hash; - -# supplying the call to the external cipher implementation -# that is being used to keep STDIN and STDOUT open -# to maintain the state of the block chaining -# $1: cipher -# $2: 1=encryption, 0=decryption -# $3: buffersize needed for openssl -# $4: encryption key in binary form -# $5: IV in binary form -# return: command line to execute the application -my $state_cipher; -# the only difference of the DES version is that it implements the inner loop -# of the TDES tests -my $state_cipher_des; - -# supplying the call to the external cipher implementation -# that is being used to keep STDIN and STDOUT open -# to maintain the state of the RNG with its seed -# -# input holds seed values -# $1: cipher key in hex format -# $2: DT value in hex format -# $3: V value in hex format -# -# return: command line to execute the application -# -# the application is expected to deliver random values on STDOUT - the script -# reads 128 bits repeatedly where the state of the RNG must be retained -# between the reads. The output of the RNG on STDOUT is assumed to be binary. -my $state_rng; - -# Generate an HMAC based on SHAx -# $1: Key to be used for the HMAC in hex format -# $2: length of the hash to be calculated in bits -# $3: Message for which the HMAC shall be calculated in hex format -# $4: hash type (1 - SHA1, 224 - SHA224, and so on) -# return: calculated HMAC in hex format -my $hmac; - -# -# Generate the P, Q, G, Seed, counter, h (value used to generate g) values -# for DSA -# $1: modulus size -# $2: q size -# $3: seed (might be empty string) -# return: string with the calculated values in hex format, where each value -# is separated from the previous with a \n in the following order: -# P\n -# Q\n -# G\n -# Seed\n -# counter\n -# h -my $dsa_pqggen; - -# Generate the G value from P and Q -# for DSA -# $1: modulus size -# $2: q size -# $3: P in hex form -# $4: Q in hex form -# return: string with the calculated values in hex format, where each value -# is separated from the previous with a \n in the following order: -# P\n -# Q\n -# G\n -my $dsa_ggen; - -# -# Generate an DSA public key from the provided parameters: -# $1: Name of file to create -# $2: P in hex form -# $3: Q in hex form -# $4: G in hex form -# $5: Y in hex form -my $dsa_genpubkey; - -# Verify a message with DSA -# $1: data to be verified in hex form -# $2: file holding the public DSA key in PEM format -# $3: R value of the signature -# $4: S value of the signature -# return: 1 == verified / 0 == not verified -my $dsa_verify; - -# generate a new DSA key with the following properties: -# PEM format -# $1: modulus size -# $2: q size -# $3 keyfile name -# return: file created with key, string with values of P, Q, G in hex format -my $gen_dsakey; - -# generate a new DSA private key XY parameters in domain: -# PEM format -# $1: P in hex form -# $2: Q in hex form -# $3: G in hex form -# return: string with values of X, Y in hex format -my $gen_dsakey_domain; - -# Sign a message with DSA -# $1: data to be signed in hex form -# $2: Key file in PEM format with the private key -# return: hash of digest information in hex format with Y, R, S as keys -my $dsa_sign; - -# interface with SP800-90A DRBG -# $1 cipher - the sign whether prediction resistance is required is visible on -# set additional entropy -# $2 expected length of output -# $3 entropy in hex -# $4 nonce in hex -# $5 personalization string in hex - if "z", string was empty -# $6 1st additional input in hex - if "z", string was empty -# $7 2nd additional input in hex - if "z", string was empty -# $8 1st additional entropy in hex - if "z", string was empty -# $9 2nd additional entropy in hex - if "z", string was empty -# return: random value in hex format -my $drbg; - -################################################################ -##### OpenSSL interface functions -################################################################ -sub openssl_encdec($$$$$) { - my $key=shift; - my $iv=shift; - my $cipher=shift; - my $enc = (shift) ? "-e" : "-d"; - my $data=shift; - - # We only invoke the driver with the IV parameter, if we have - # an IV, otherwise, we skip it - $iv = "-iv $iv" if ($iv); - - $data=hex2bin($data); - my $program="openssl enc -$cipher -nopad -nosalt -K $key $enc $iv"; - $program = "rc4 -k $key" if $opt{'R'}; #for ARCFOUR, no IV must be given - $data=pipe_through_program($data,$program); - return bin2hex($data); -} - -sub openssl_rsa_sign($$$) { - my $data = shift; - my $cipher = shift; - my $keyfile = shift; - - $data=hex2bin($data); - die "ARCFOUR not available for RSA" if $opt{'R'}; - $data=pipe_through_program($data, - "openssl dgst -$cipher -binary -sign $keyfile"); - return bin2hex($data); -} - -sub openssl_rsa_verify($$$$) { - my $data = shift; - my $cipher = shift; - my $keyfile = shift; - my $sigfile = shift; - - $data = hex2bin($data); - die "ARCFOUR not available for RSA" if $opt{'R'}; - $data = pipe_through_program($data, - "openssl dgst -$cipher -binary -verify $keyfile -signature $sigfile"); - - # Parse through the OpenSSL output information - return ($data =~ /OK/); -} - -sub openssl_gen_rsakey($$) { - my $keylen = shift; - my $file = shift; - - die "ARCFOUR not available for RSA" if $opt{'R'}; - # generating of a key with exponent 0x10001 - my @args = ("openssl", "genrsa", "-F4", "-out", "$file", "$keylen"); - system(@args) == 0 - or die "system @args failed: $?"; - die "system @args failed: file $file not created" if (! -f $file); -} - -sub openssl_hash($$) { - my $pt = shift; - my $cipher = shift; - - die "ARCFOUR not available for hashes" if $opt{'R'}; - my $hash = hex2bin($pt); - #bin2hex not needed as the '-hex' already converts it - return pipe_through_program($hash, "openssl dgst -$cipher -hex"); -} - -sub openssl_state_cipher($$$$$) { - my $cipher = shift; - my $encdec = shift; - my $bufsize = shift; - my $key = shift; - my $iv = shift; - - my $enc = $encdec ? "-e": "-d"; - - # We only invoke the driver with the IV parameter, if we have - # an IV, otherwise, we skip it - $iv = "-iv ".bin2hex($iv) if ($iv); - - my $out = "openssl enc -'$cipher' $enc -nopad -nosalt -bufsize $bufsize -K ".bin2hex($key)." $iv"; - #for ARCFOUR, no IV must be given - $out = "rc4 -k " . bin2hex($key) if $opt{'R'}; - return $out; -} - -###### End of OpenSSL interface implementation ############ - -########################################################### -###### libgcrypt implementation -########################################################### -sub libgcrypt_encdec($$$$$) { - my $key=shift; - my $iv=shift; - my $cipher=shift; - my $enc = (shift) ? "encrypt" : "decrypt"; - my $data=shift; - - # We only invoke the driver with the IV parameter, if we have - # an IV, otherwise, we skip it - $iv = "--iv $iv" if ($iv); - - my $program="fipsdrv --key $key $iv --algo $cipher $enc"; - - return pipe_through_program($data,$program); - -} - -sub libgcrypt_rsa_derive($$$$$$$$) { - my $n = shift; - my $e = shift; - my $xp1 = shift; - my $xp2 = shift; - my $xp = shift; - my $xq1 = shift; - my $xq2 = shift; - my $xq = shift; - my $sexp; - my @tmp; - - $n = sprintf ("%u", $n); - $e = sprintf ("%u", hex($e)); - $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" - . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")" - . "(derive-parms" - . "(Xp1 #$xp1#)" - . "(Xp2 #$xp2#)" - . "(Xp #$xp#)" - . "(Xq1 #$xq1#)" - . "(Xq2 #$xq2#)" - . "(Xq #$xq#))))\n"; - - return pipe_through_program($sexp, "fipsdrv rsa-derive"); -} - - -sub libgcrypt_rsa_sign($$$) { - my $data = shift; - my $hashalgo = shift; - my $keyfile = shift; - - die "ARCFOUR not available for RSA" if $opt{'R'}; - - return pipe_through_program($data, - "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile rsa-sign"); -} - -sub libgcrypt_rsa_verify($$$$) { - my $data = shift; - my $hashalgo = shift; - my $keyfile = shift; - my $sigfile = shift; - - die "ARCFOUR not available for RSA" if $opt{'R'}; - $data = pipe_through_program($data, - "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify"); - - # Parse through the output information - return ($data =~ /GOOD signature/); -} - -sub libgcrypt_gen_rsakey($$) { - my $keylen = shift; - my $file = shift; - - die "ARCFOUR not available for RSA" if $opt{'R'}; - my @args = ("fipsdrv --keysize $keylen rsa-gen > $file"); - system(@args) == 0 - or die "system @args failed: $?"; - die "system @args failed: file $file not created" if (! -f $file); -} - -sub libgcrypt_hash($$) { - my $pt = shift; - my $hashalgo = shift; - - my $program = "fipsdrv --algo $hashalgo digest"; - die "ARCFOUR not available for hashes" if $opt{'R'}; - - return pipe_through_program($pt, $program); -} - -sub libgcrypt_state_cipher($$$$$) { - my $cipher = shift; - my $enc = (shift) ? "encrypt": "decrypt"; - my $bufsize = shift; - my $key = shift; - my $iv = shift; - - # We only invoke the driver with the IV parameter, if we have - # an IV, otherwise, we skip it - $iv = "--iv ".bin2hex($iv) if ($iv); - - my $program="fipsdrv --binary --key ".bin2hex($key)." $iv --algo '$cipher' --chunk '$bufsize' $enc"; - - return $program; -} - -sub libgcrypt_state_cipher_des($$$$$) { - my $cipher = shift; - my $enc = (shift) ? "encrypt": "decrypt"; - my $bufsize = shift; - my $key = shift; - my $iv = shift; - - # We only invoke the driver with the IV parameter, if we have - # an IV, otherwise, we skip it - $iv = "--iv ".bin2hex($iv) if ($iv); - - my $program="fipsdrv --algo '$cipher' --mct-server $enc"; - - return $program; -} - -sub libgcrypt_state_rng($$$) { - my $key = shift; - my $dt = shift; - my $v = shift; - - return "fipsdrv --binary --loop --key $key --iv $v --dt $dt random"; -} - -sub libgcrypt_hmac($$$$) { - my $key = shift; - my $maclen = shift; - my $msg = shift; - my $hashtype = shift; - - my $program = "fipsdrv --key $key --algo $hashtype hmac-sha"; - return pipe_through_program($msg, $program); -} - -sub libgcrypt_dsa_pqggen($$$) { - my $mod = shift; - my $qsize = shift; - my $seed = shift; - - my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; - return pipe_through_program($seed, $program); -} - -sub libgcrypt_dsa_ggen($$$$) { - my $mod = shift; - my $qsize = shift; - my $p = shift; - my $q = shift; - my $domain = "(domain (p #$p#)(q #$q#))"; - - my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; - return pipe_through_program("", $program); -} - -sub libgcrypt_gen_dsakey($$$) { - my $mod = shift; - my $qsize = shift; - my $file = shift; - - my $program = "fipsdrv --keysize $mod --qsize $qsize --key $file dsa-gen"; - my $tmp; - my %ret; - - die "ARCFOUR not available for DSA" if $opt{'R'}; - - $tmp = pipe_through_program("", $program); - die "dsa key gen failed: file $file not created" if (! -f $file); - - @ret{'P', 'Q', 'G'} = split(/\n/, $tmp); - return %ret; -} - -sub libgcrypt_gen_dsakey_domain($$$) { - my $p = shift; - my $q = shift; - my $g = shift; - my $domain = "(domain (p #$p#)(q #$q#)(g #$g#))"; - - my $program = "fipsdrv --key '$domain' dsa-gen-key"; - - return pipe_through_program("", $program); -} - -sub libgcrypt_dsa_genpubkey($$$$$) { - my $filename = shift; - my $p = shift; - my $q = shift; - my $g = shift; - my $y = shift; - - my $sexp; - - $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))"; - - open(FH, ">", $filename) or die; - print FH $sexp; - close FH; -} - -sub libgcrypt_dsa_sign($$) { - my $data = shift; - my $keyfile = shift; - my $tmp; - my %ret; - - die "ARCFOUR not available for DSA" if $opt{'R'}; - - $tmp = pipe_through_program($data, "fipsdrv --key $keyfile dsa-sign"); - @ret{'Y', 'R', 'S'} = split(/\n/, $tmp); - return %ret; -} - -sub libgcrypt_dsa_verify($$$$) { - my $data = shift; - my $keyfile = shift; - my $r = shift; - my $s = shift; - - my $ret; - - die "ARCFOUR not available for DSA" if $opt{'R'}; - - my $sigfile = "$keyfile.sig"; - open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?"; - print FH "(sig-val(dsa(r #$r#)(s #$s#)))"; - close FH; - - $ret = pipe_through_program($data, - "fipsdrv --key $keyfile --signature $sigfile dsa-verify"); - unlink ($sigfile); - # Parse through the output information - return ($ret =~ /GOOD signature/); -} - -sub libgcrypt_drbg($$$$$$$$$) { - my $cipher = shift; - my $drbg_expectedlen = shift; - my $drbg_entropy = shift; - my $drbg_nonce = shift; - my $drbg_pers = shift; - my $drbg_addtla = shift; - my $drbg_addtlb = shift; - my $drbg_entpra = shift; - my $drbg_entprb = shift; - my $out = ""; - my $parameter = ""; - my $flags = 0; - - $drbg_expectedlen = $drbg_expectedlen / 8; - - if ($cipher =~ /aes128/) { - $flags |= (1 << 0 | 1 << 13); - } - if ($cipher =~ /aes192/) { - $flags |= (1 << 0 | 1 << 14); - } - if ($cipher =~ /aes256/) { - $flags |= (1 << 0 | 1 << 15); - } - if ($cipher =~ /sha1/) { - $flags |= 1 << 4; - } - if ($cipher =~ /sha256/) { - $flags |= 1 << 6; - } - if ($cipher =~ /sha384/) { - $flags |= 1 << 7; - } - if ($cipher =~ /sha512/) { - $flags |= 1 << 8; - } - if ($cipher =~ /hmac/) { - $flags |= 1 << 12; - } - - if ($drbg_entpra ne "" && $drbg_entprb ne "") { - $flags |= 1 << 28; - } - - $parameter .= " -f $flags"; - # test drvier requires concatenated entropy/nonce - $drbg_entropy = $drbg_entropy . $drbg_nonce; - $parameter .= " -e $drbg_entropy"; - $parameter .= " -l $drbg_expectedlen"; - if ($drbg_pers ne "z") { $parameter .= " -p $drbg_pers"; } - if ($drbg_addtla ne "z") { $parameter .= " -c $drbg_addtla";} - if ($drbg_addtlb ne "z") { $parameter .= " -d $drbg_addtlb";} - if ($drbg_entpra ne "z" && $drbg_entpra ne "") { - $parameter .= " -y $drbg_entpra"; - } - if ($drbg_entprb ne "z" && $drbg_entprb ne "") { - $parameter .= " -z $drbg_entprb"; - } - - $out = pipe_through_program("", - "/usr/lib/libgcrypt/drbg_test $parameter 2>/dev/null"); - - return $out; -} - - -######### End of libgcrypt implementation ################ - -################################################################ -###### Kernel Crypto API interface functions -################################################################ - -#my $DIR = "/sys/kernel/debug/cryptoapi/"; -my $DIR = "/sys/kernel/debug/drbg-cavs/"; -my $CIPHER_AES = Math::BigInt->new("0x0000000000000001"); -my $CIPHER_TDES = Math::BigInt->new("0x0000000000000002"); - -my $CIPHER_SHA1 = Math::BigInt->new("0x0000000000010000"); -my $CIPHER_SHA224 = Math::BigInt->new("0x0000000000020000"); -my $CIPHER_SHA256 = Math::BigInt->new("0x0000000000040000"); -my $CIPHER_SHA384 = Math::BigInt->new("0x0000000000100000"); -my $CIPHER_SHA512 = Math::BigInt->new("0x0000000000200000"); - -my $CIPHER_X931RNG = Math::BigInt->new("0x0000000001000000"); - -my $TYPE_CTR = Math::BigInt->new("0x0010000000000000"); -my $TYPE_GENERIC = Math::BigInt->new("0x0020000000000000"); -my $TYPE_ASM = Math::BigInt->new("0x0040000000000000"); -my $TYPE_CBC = Math::BigInt->new("0x0100000000000000"); -my $TYPE_ECB = Math::BigInt->new("0x0200000000000000"); -my $TYPE_KEEP = Math::BigInt->new("0x0400000000000000"); -my $TYPE_HMAC = Math::BigInt->new("0x1000000000000000"); -my $TYPE_ENC = Math::BigInt->new("0x2000000000000000"); -my $TYPE_DEC = Math::BigInt->new("0x4000000000000000"); - -sub writedata($$) { - my $file=shift; - my $data=shift; - $file = $DIR . $file; - open(FH, ">$file") or die "Cannot open file $file"; - my $dlen = length($data); - my $len = syswrite(FH, $data, $dlen); - if($len != $dlen) { - die "Cannot write data of length $dlen"; - } - close(FH); -} - -sub readdata($$) { - my $file=shift; - my $bytes=shift; - my $out; - $file = $DIR . $file; - open(FH, "<$file") or die "Cannot open file $file"; - my $len = sysread(FH, $out, $bytes); - if(!defined($len)) { - $out=""; - } - return $out; -} - -sub cryptoapi_setupencdec($$$$$) { - my $key=shift; - my $iv=shift; - my $cipher=shift; - my $enc = shift; - my $keep = shift; - - # enc / dec yet unhandled - should not matter anyhow - if($cipher eq "des-ede3-cbc") { - $cipher = $CIPHER_TDES|$TYPE_CBC; - } elsif($cipher eq "des-ede3") { - $cipher = $CIPHER_TDES|$TYPE_ECB; - } elsif($cipher =~ /^aes-\d{3}-cbc$/) { - $cipher = $CIPHER_AES|$TYPE_CBC; - } elsif($cipher =~ /^aes-\d{3}-ecb$/) { - $cipher = $CIPHER_AES|$TYPE_ECB; - } else { - die "Unknown cipher $cipher for kernel crypto API"; - } - if($enc) { - $cipher = $cipher | $TYPE_ENC; - } else { - $cipher = $cipher | $TYPE_DEC; - } - if($keep) { - $cipher = $cipher | $TYPE_KEEP; - } - - # DIFFERENT IMPLEMENTATION enable generic implementation! - # $cipher = $cipher | $TYPE_GENERIC; - - # DIFFERENT IMPLEMENTATION enable asm implementation! - # $cipher = $cipher | $TYPE_ASM; - - $cipher = $cipher->as_hex; - - writedata("cipher", $cipher); - writedata("key", hex2bin($key)); - - # We only invoke the driver with the IV parameter, if we have - # an IV, otherwise, we skip it - if(defined($iv)) { - writedata("iv", hex2bin($iv)); - } -} - -sub cryptoapi_encdec($$$$$) { - my $key=shift; - my $iv=shift; - my $cipher=shift; - my $enc = shift; - my $data = shift; - cryptoapi_setupencdec($key, $iv, $cipher, $enc, 0); - writedata("data", hex2bin($data)); - my $out; - $out = readdata("data", 100000); - return bin2hex($out); -} - -sub cryptoapi_state_cipher($$$$$) { - my $cipher = shift; - my $enc = shift; - my $bufsize = shift; - my $key = bin2hex(shift); - my $iv = shift; - $iv = bin2hex($iv) if ($iv); - cryptoapi_setupencdec($key, $iv, $cipher, $enc, 1); - my $file = $DIR . "data"; - return "statewrapper.pl $file $bufsize"; -} - -sub cryptoapi_hash($$) { - my $pt = shift; - my $hashalgo = shift; - - my $out; - if($hashalgo eq "sha1") { - $hashalgo = $CIPHER_SHA1; - } elsif($hashalgo eq "sha224") { - $hashalgo = $CIPHER_SHA224; - } elsif($hashalgo eq "sha256") { - $hashalgo = $CIPHER_SHA256; - } elsif($hashalgo eq "sha384") { - $hashalgo = $CIPHER_SHA384; - } elsif($hashalgo eq "sha512") { - $hashalgo = $CIPHER_SHA512; - } else { - die "Unknown hashalgo $hashalgo for kernel crypto API"; - } - - # DIFFERENT IMPLEMENTATION enable generic implementation! - # $hashalgo = $hashalgo | $TYPE_GENERIC; - - $hashalgo = $hashalgo->as_hex; - writedata("cipher", $hashalgo); - writedata("data", hex2bin($pt)); - - die "ARCFOUR not available for hashes" if $opt{'R'}; - - $out = readdata("data", 100000); - return bin2hex($out); -} - -sub cryptoapi_hmac($$$$) { - my $key = shift; - my $maclen = shift; - my $msg = shift; - my $hashtype = shift; - - my $out; - if($hashtype eq "1") { - $hashtype = $CIPHER_SHA1 | $TYPE_HMAC; - } elsif($hashtype eq "224") { - $hashtype = $CIPHER_SHA224 | $TYPE_HMAC; - } elsif($hashtype eq "256") { - $hashtype = $CIPHER_SHA256 | $TYPE_HMAC; - } elsif($hashtype eq "384") { - $hashtype = $CIPHER_SHA384 | $TYPE_HMAC; - } elsif($hashtype eq "512") { - $hashtype = $CIPHER_SHA512 | $TYPE_HMAC; - } else { - die "Unknown hashalgo $hashtype for kernel crypto API"; - } - - # DIFFERENT IMPLEMENTATION enable generic implementation! - # $hashtype = $hashalgo | $TYPE_GENERIC; - - $hashtype = $hashtype->as_hex; - writedata("cipher", $hashtype); - writedata("key", hex2bin($key)); - writedata("data", hex2bin($msg)); - - $out = readdata("data", 100000); - return bin2hex($out); -} - -sub cryptoapi_state_rng($$$) { - my $key = shift; - my $dt = shift; - my $v = shift; - - my $seed = $v . $key . $dt; - $seed=hex2bin($seed); - - writedata("cipher", $CIPHER_X931RNG->as_hex); - writedata("key", $seed); - - my $file = $DIR . "data"; - return "statewrapper.pl $file"; -} - -sub cryptoapi_drbg($$$$$$$$$) { - my $cipher = shift; - my $drbg_expectedlen = shift; - my $drbg_entropy = shift; - my $drbg_nonce = shift; - my $drbg_pers = shift; - my $drbg_addtla = shift; - my $drbg_addtlb = shift; - my $drbg_entpra = shift; - my $drbg_entprb = shift; - my $out = ""; - - $drbg_expectedlen = $drbg_expectedlen / 8; - - if ($cipher =~ /hash\s+(\w+)/) { $cipher = $1; } - if ($cipher =~ /hmac\s+(\w+)/) { $cipher = "hmac($1)"; } - if ($cipher =~ /ctr\s+(\w+)/) { $cipher = "ctr($1)"; } - - if ($drbg_entpra ne "" && $drbg_entprb ne "") { - $cipher = "drbg(pr($cipher))"; - } else { - $cipher = "drbg(nopr($cipher))"; - } - - # test drvier requires concatenated entropy/nonce - $drbg_entropy = $drbg_entropy . $drbg_nonce; - writedata("name", $cipher); - writedata("entropy", hex2bin($drbg_entropy)); - if ($drbg_pers ne "z") { writedata("pers", hex2bin($drbg_pers)); } - if ($drbg_addtla ne "z") { writedata("addtla", hex2bin($drbg_addtla));} - if ($drbg_addtlb ne "z") { writedata("addtlb", hex2bin($drbg_addtlb));} - if ($drbg_entpra ne "z" && $drbg_entpra ne "") { - writedata("entpra", hex2bin($drbg_entpra)); - } - if ($drbg_entprb ne "z" && $drbg_entprb ne "") { - writedata("entprb", hex2bin($drbg_entprb)); - } - $out = readdata("data", $drbg_expectedlen); - $out = bin2hex($out); - return $out; -} - -################################################################ -###### Vendor1 interface functions -################################################################ - -sub vendor1_encdec($$$$$) { - my $key=shift; - my $iv=shift; - my $cipher=shift; - my $enc = (shift) ? "encrypt" : "decrypt"; - my $data=shift; - - $data=hex2bin($data); - my $program = "./aes $enc $key"; - $data=pipe_through_program($data,$program); - return bin2hex($data); -} - -sub vendor1_state_cipher($$$$$) { - my $cipher = shift; - my $encdec = shift; - my $bufsize = shift; - my $key = shift; - my $iv = shift; - - $key = bin2hex($key); - my $enc = $encdec ? "encrypt": "decrypt"; - my $out = "./aes $enc $key $bufsize"; - return $out; -} - -##### No other interface functions below this point ###### -########################################################## - -########################################################## -# General helper routines - -# Executing a program by feeding STDIN and retrieving -# STDOUT -# $1: data string to be piped to the app on STDIN -# rest: program and args -# returns: STDOUT of program as string -sub pipe_through_program($@) { - my $in = shift; - my @args = @_; - - my ($CO, $CI); - my $pid = open2($CO, $CI, @args); - - my $out = ""; - my $len = length($in); - my $first = 1; - while (1) { - my $rin = ""; - my $win = ""; - # Output of prog is FD that we read - vec($rin,fileno($CO),1) = 1; - # Input of prog is FD that we write - # check for $first is needed because we can have NULL input - # that is to be written to the app - if ( $len > 0 || $first) { - (vec($win,fileno($CI),1) = 1); - $first=0; - } - # Let us wait for 100ms - my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1); - if ( $wout ) { - my $written = syswrite($CI, $in, $len); - die "broken pipe" if !defined $written; - $len -= $written; - substr($in, 0, $written) = ""; - if ($len <= 0) { - close $CI or die "broken pipe: $!"; - } - } - if ( $rout ) { - my $tmp_out = ""; - my $bytes_read = sysread($CO, $tmp_out, 4096); - $out .= $tmp_out; - last if ($bytes_read == 0); - } - } - close $CO or die "broken pipe: $!"; - waitpid $pid, 0; - - return $out; -} - -# -# convert ASCII hex to binary input -# $1 ASCII hex -# return binary representation -sub hex2bin($) { - my $in = shift; - my $len = length($in); - $len = 0 if ($in eq "00"); - return pack("H$len", "$in"); -} - -# -# convert binary input to ASCII hex -# $1 binary value -# return ASCII hex representation -sub bin2hex($) { - my $in = shift; - my $len = length($in)*2; - return unpack("H$len", "$in"); -} - -# $1: binary byte (character) -# returns: binary byte with odd parity using low bit as parity bit -sub odd_par($) { - my $in = ord(shift); - my $odd_count=0; - for(my $i=1; $i<8; $i++) { - $odd_count++ if ($in & (1<<$i)); - } - - my $out = $in; - if ($odd_count & 1) { # check if parity is already odd - $out &= ~1; # clear the low bit - } else { - $out |= 1; # set the low bit - } - - return chr($out); -} - -# DES keys uses only the 7 high bits of a byte, the 8th low bit -# is the parity bit -# as the new key is calculated from oldkey XOR cipher in the MCT test, -# the parity is not really checked and needs to be set to match -# expectation (OpenSSL does not really care, but the FIPS -# test result is expected that the key has the appropriate parity) -# $1: arbitrary binary string -# returns: string with odd parity set in low bit of each byte -sub fix_key_parity($) { - my $in = shift; - my $out = ""; - for (my $i = 0; $i < length($in); $i++) { - $out .= odd_par(substr($in, $i, 1)); - } - - return $out; -} - -#################################################### -# DER/PEM utility functions -# Cf. http://www.columbia.edu/~ariel/ssleay/layman.html - -# Convert unsigned integer to base256 bigint bytes -# $1 integer -# returns base256 octet string -sub int_base256_unsigned($) { - my $n = shift; - - my $out = chr($n & 255); - while ($n>>=8) { - $out = chr($n & 255) . $out; - } - - return $out; -} - -# Convert signed integer to base256 bigint bytes -# $1 integer -# returns base256 octet string -sub int_base256_signed($) { - my $n = shift; - my $negative = ($n < 0); - - if ($negative) { - $n = -$n-1; - } - - my $out = int_base256_unsigned($n); - - if (ord(substr($out, 0, 1)) & 128) { - # it's supposed to be positive but has sign bit set, - # add a leading zero - $out = chr(0) . $out; - } - - if ($negative) { - my $neg = chr(255) x length($out); - $out ^= $neg; - } - - return $out; -} - -# Length header for specified DER object length -# $1 length as integer -# return octet encoding for length -sub der_len($) { - my $len = shift; - - if ($len <= 127) { - return chr($len); - } else { - my $blen = int_base256_unsigned($len); - - return chr(128 | length($blen)) . $blen; - } -} - -# Prepend length header to object -# $1 object as octet sequence -# return length header for object followed by object as octets -sub der_len_obj($) { - my $x = shift; - - return der_len(length($x)) . $x; -} - -# DER sequence -# $* objects -# returns DER sequence consisting of the objects passed as arguments -sub der_seq { - my $seq = join("", @_); - return chr(0x30) . der_len_obj($seq); -} - -# DER bitstring -# $1 input octets (must be full octets, fractional octets not supported) -# returns input encapsulated as bitstring -sub der_bitstring($) { - my $x = shift; - - $x = chr(0) . $x; - - return chr(0x03) . der_len_obj($x); -} - -# base-128-encoded integer, used for object numbers. -# $1 integer -# returns octet sequence -sub der_base128($) { - my $n = shift; - - my $out = chr($n & 127); - - while ($n>>=7) { - $out = chr(128 | ($n & 127)) . $out; - } - - return $out; -} - -# Generating the PEM certificate string -# (base-64-encoded DER string) -# $1 DER string -# returns octet sequence -sub pem_cert($) { - my $n = shift; - - my $out = "-----BEGIN PUBLIC KEY-----\n"; - $out .= encode_base64($n); - $out .= "-----END PUBLIC KEY-----\n"; - - return $out; -} - -# DER object identifier -# $* sequence of id numbers -# returns octets -sub der_objectid { - my $v1 = shift; - my $v2 = shift; - - my $out = chr(40*$v1 + $v2) . join("", map { der_base128($_) } @_); - - return chr(0x06) . der_len_obj($out); -} - -# DER signed integer -# $1 number as octet string (base 256 representation, high byte first) -# returns number in DER integer encoding -sub der_bigint($) { - my $x = shift; - - return chr(0x02) . der_len_obj($x); -} - -# DER positive integer with leading zeroes stripped -# $1 number as octet string (base 256 representation, high byte first) -# returns number in DER integer encoding -sub der_pos_bigint($) { - my $x = shift; - - # strip leading zero digits - $x =~ s/^[\0]+//; - - # need to prepend a zero if high bit set, since it would otherwise be - # interpreted as a negative number. Also needed for number 0. - if (!length($x) || ord(substr($x, 0, 1)) >= 128) { - $x = chr(0) . $x; - } - - return der_bigint($x); -} - -# $1 number as signed integer -# returns number as signed DER integer encoding -sub der_int($) { - my $n = shift; - - return der_bigint(int_base256_signed($n)); -} - -# the NULL object constant -sub der_null() { - return chr(0x05) . chr(0x00); -} - -# Unit test helper -# $1 calculated result -# $2 expected result -# no return value, dies if results differ, showing caller's line number -sub der_test($$) { - my $actual = bin2hex(shift); - my $expected = shift; - - my @caller = caller; - $actual eq $expected or die "Error:line $caller[2]:assertion failed: " - ."$actual != $expected\n"; -} - -# Unit testing for the DER encoding functions -# Examples from http://www.columbia.edu/~ariel/ssleay/layman.html -# No input, no output. Dies if unit tests fail. -sub der_unit_test { - ## uncomment these if you want to test the test framework - #print STDERR "Unit test running\n"; - #der_test chr(0), "42"; - - der_test der_null, "0500"; - - # length bytes - der_test der_len(1), "01"; - der_test der_len(127), "7f"; - der_test der_len(128), "8180"; - der_test der_len(256), "820100"; - der_test der_len(65536), "83010000"; - - # bigint - der_test der_bigint(chr(0)), "020100"; - der_test der_bigint(chr(128)), "020180"; # -128 - der_test der_pos_bigint(chr(128)), "02020080"; # +128 - der_test der_pos_bigint(chr(0).chr(0).chr(1)), "020101"; - der_test der_pos_bigint(chr(0)), "020100"; - - # integers (tests base256 conversion) - der_test der_int( 0), "020100"; - der_test der_int( 127), "02017f"; - der_test der_int( 128), "02020080"; - der_test der_int( 256), "02020100"; - der_test der_int( -1), "0201ff"; - der_test der_int( -128), "020180"; - der_test der_int( -129), "0202ff7f"; - der_test der_int(-65536), "0203ff0000"; - der_test der_int(-65537), "0203feffff"; - - # object encoding, "RSA Security" - der_test der_base128(840), "8648"; - der_test der_objectid(1, 2, 840, 113549), "06062a864886f70d"; - - # Combinations - der_test der_bitstring("ABCD"), "03050041424344"; - der_test der_bitstring(der_null), "0303000500"; - der_test der_seq(der_int(0), der_null), "30050201000500"; - - # The big picture - der_test der_seq(der_seq(der_objectid(1, 2, 840, 113549), der_null), - der_bitstring(der_seq(der_pos_bigint(chr(5)), - der_pos_bigint(chr(3))))), - "3017300a06062a864886f70d05000309003006020105020103"; -} - -#################################################### -# OpenSSL missing functionality workarounds - -## Format of an RSA public key: -# 0:d=0 hl=3 l= 159 cons: SEQUENCE -# 3:d=1 hl=2 l= 13 cons: SEQUENCE -# 5:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption -# 16:d=2 hl=2 l= 0 prim: NULL -# 18:d=1 hl=3 l= 141 prim: BIT STRING -# [ sequence: INTEGER (n), INTEGER (e) ] - -# generate RSA pub key in PEM format -# $1: filename where PEM key is to be stored -# $2: n of the RSA key in hex -# $3: e of the RSA key in hex -# return: nothing, but file created -sub gen_pubrsakey($$$) { - my $filename=shift; - my $n = shift; - my $e = shift; - - # make sure the DER encoder works ;-) - der_unit_test(); - - # generate DER encoding of the public key - - my $rsaEncryption = der_objectid(1, 2, 840, 113549, 1, 1, 1); - - my $der = der_seq(der_seq($rsaEncryption, der_null), - der_bitstring(der_seq(der_pos_bigint(hex2bin($n)), - der_pos_bigint(hex2bin($e))))); - - open(FH, ">", $filename) or die; - print FH pem_cert($der); - close FH; - -} - -# generate RSA pub key in PEM format -# -# This implementation uses "openssl asn1parse -genconf" which was added -# in openssl 0.9.8. It is not available in older openssl versions. -# -# $1: filename where PEM key is to be stored -# $2: n of the RSA key in hex -# $3: e of the RSA key in hex -# return: nothing, but file created -sub gen_pubrsakey_using_openssl($$$) { - my $filename=shift; - my $n = shift; - my $e = shift; - - my $asn1 = "asn1=SEQUENCE:pubkeyinfo - -[pubkeyinfo] -algorithm=SEQUENCE:rsa_alg -pubkey=BITWRAP,SEQUENCE:rsapubkey - -[rsa_alg] -algorithm=OID:rsaEncryption -parameter=NULL - -[rsapubkey] -n=INTEGER:0x$n - -e=INTEGER:0x$e"; - - open(FH, ">$filename.cnf") or die "Cannot create file $filename.cnf: $?"; - print FH $asn1; - close FH; - my @args = ("openssl", "asn1parse", "-genconf", "$filename.cnf", "-noout", "-out", "$filename.der"); - system(@args) == 0 or die "system @args failed: $?"; - @args = ("openssl", "rsa", "-inform", "DER", "-in", "$filename.der", - "-outform", "PEM", "-pubin", "-pubout", "-out", "$filename"); - system(@args) == 0 or die "system @args failed: $?"; - die "RSA PEM formatted key file $filename was not created" - if (! -f $filename); - - unlink("$filename.cnf"); - unlink("$filename.der"); -} - -############################################ -# Test cases - -# This is the Known Answer Test -# $1: the string that we have to put in front of the key -# when printing the key -# $2: crypto key1 in hex form -# $3: crypto key2 in hex form (TDES, undef otherwise) -# $4: crypto key3 in hex form (TDES, undef otherwise) -# $5: IV in hex form -# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form -# $7: cipher -# $8: encrypt=1/decrypt=0 -# return: string formatted as expected by CAVS -sub kat($$$$$$$$) { - my $keytype = shift; - my $key1 = shift; - my $key2 = shift; - my $key3 = shift; - my $iv = shift; - my $pt = shift; - my $cipher = shift; - my $enc = shift; - - my $out = ""; - - $out .= "$keytype = $key1\n"; - - # this is the concardination of the keys for 3DES - if (defined($key2)) { - $out .= "KEY2 = $key2\n"; - $key1 = $key1 . $key2; - } - if (defined($key3)) { - $out .= "KEY3 = $key3\n"; - $key1= $key1 . $key3; - } - - $out .= "IV = $iv\n" if (defined($iv) && $iv ne ""); - if ($enc) { - $out .= "PLAINTEXT = $pt\n"; - $out .= "CIPHERTEXT = " . &$encdec($key1, $iv, $cipher, 1, $pt) . "\n"; - } else { - $out .= "CIPHERTEXT = $pt\n"; - $out .= "PLAINTEXT = " . &$encdec($key1, $iv, $cipher, 0, $pt) . "\n"; - } - - return $out; -} - -# This is the Known Answer Test for Hashes -# $1: Plaintext in hex form -# $2: hash -# $3: hash length (undef if not applicable) -# return: string formatted as expected by CAVS -sub hash_kat($$$) { - my $pt = shift; - my $cipher = shift; - my $len = shift; - - my $out = ""; - $out .= "Len = $len\n" if (defined($len)); - $out .= "Msg = $pt\n"; - - $pt = "" if(!$len); - $out .= "MD = " . &$hash($pt, $cipher) . "\n"; - return $out; -} - -# Known Answer Test for HMAC hash -# $1: key length in bytes -# $2: MAC length in bytes -# $3: key for HMAC in hex form -# $4: message to be hashed -# return: string formatted as expected by CAVS -sub hmac_kat($$$$) { - my $klen = shift; - my $tlen = shift; - my $key = shift; - my $msg = shift; - - # XXX this is a hack - we need to decipher the HMAC REQ files in a more - # sane way - # - # This is a conversion table from the expected hash output size - # to the assumed hash type - we only define here the block size of - # the underlying hashes and do not allow any truncation - my %hashtype = ( - 20 => 1, - 28 => 224, - 32 => 256, - 48 => 384, - 64 => 512 - ); - - die "Hash output size $tlen is not supported!" - if(!defined($hashtype{$tlen})); - - my $out = ""; - $out .= "Klen = $klen\n"; - $out .= "Tlen = $tlen\n"; - $out .= "Key = $key\n"; - $out .= "Msg = $msg\n"; - $out .= "Mac = " . lc(&$hmac($key, $tlen, $msg, $hashtype{$tlen})) . "\n"; - - return $out; -} - - -# Cipher Monte Carlo Testing -# $1: the string that we have to put in front of the key -# when printing the key -# $2: crypto key1 in hex form -# $3: crypto key2 in hex form (TDES, undef otherwise) -# $4: crypto key3 in hex form (TDES, undef otherwise) -# $5: IV in hex form -# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form -# $7: cipher -# $8: encrypt=1/decrypt=0 -# return: string formatted as expected by CAVS -sub crypto_mct($$$$$$$$) { - my $keytype = shift; - my $key1 = hex2bin(shift); - my $key2 = shift; - my $key3 = shift; - my $iv = hex2bin(shift); - my $source_data = hex2bin(shift); - my $cipher = shift; - my $enc = shift; - - my $out = ""; - - $key2 = hex2bin($key2) if (defined($key2)); - $key3 = hex2bin($key3) if (defined($key3)); - my $bufsize = length($source_data); - - # for AES: outer loop 0-99, inner 0-999 based on FIPS compliance tests - # for RC4: outer loop 0-99, inner 0-999 based on atsec compliance tests - # for DES: outer loop 0-399, inner 0-9999 based on FIPS compliance tests - my $ciph = substr($cipher,0,3); - my $oloop=100; - my $iloop=1000; - if ($ciph =~ /des/) {$oloop=400;$iloop=10000;} - - for (my $i=0; $i<$oloop; ++$i) { - $out .= "COUNT = $i\n"; - if (defined($key2)) { - $out .= "$keytype = ". bin2hex($key1). "\n"; - $out .= "KEY2 = ". bin2hex($key2). "\n"; - $key1 = $key1 . $key2; - } else { - $out .= "$keytype = ". bin2hex($key1). "\n"; - } - if(defined($key3)) { - $out .= "KEY3 = ". bin2hex($key3). "\n"; - $key1 = $key1 . $key3; - } - my $keylen = length($key1); - - $out .= "IV = ". bin2hex($iv) . "\n" - if (defined($iv) && $iv ne ""); - - if ($enc) { - $out .= "PLAINTEXT = ". bin2hex($source_data). "\n"; - } else { - $out .= "CIPHERTEXT = ". bin2hex($source_data). "\n"; - } - my ($CO, $CI); - my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); - $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/ && defined($state_cipher_des)); - my $pid = open2($CO, $CI, $cipher_imp); - - my $calc_data = $iv; # CT[j] - my $old_calc_data; # CT[j-1] - my $old_old_calc_data; # CT[j-2] - my $next_source; - - # TDES inner loop implements logic within driver of libgcrypt - if ($cipher =~ /des/ && $opt{'I'} && $opt{'I'} eq 'libgcrypt' ) { - # Need to provide a dummy IV in case of ECB mode. - my $iv_arg = (defined($iv) && $iv ne "") - ? bin2hex($iv) - : "00"x(length($source_data)); - print $CI "1\n" - .$iloop."\n" - .bin2hex($key1)."\n" - .$iv_arg."\n" - .bin2hex($source_data)."\n\n" or die; - chomp(my $line = <$CO>); - $calc_data = hex2bin($line); - chomp($line = <$CO>); - $old_calc_data = hex2bin($line); - chomp($line = <$CO>); - $old_old_calc_data = hex2bin($line); - chomp($line = <$CO>); - $iv = hex2bin($line) if (defined($iv) && $iv ne ""); - chomp($line = <$CO>); - $next_source = hex2bin($line); - # Skip over empty line. - $line = <$CO>; - } else { - for (my $j = 0; $j < $iloop; ++$j) { - if ($cipher =~ /des-ede3-ofb/ || - (!$enc && $cipher =~ /des-ede3-cfb/)) { - die "Implementation lacks support for TDES OFB and TDES CFB in encryption mode - the problem is that we would need to extract the IV of the last round of encryption which would be the input for the next round - see comments in this script for implementation requirements"; - } - $old_old_calc_data = $old_calc_data; - $old_calc_data = $calc_data; - - #print STDERR "source_data=", bin2hex($source_data), "\n"; - syswrite $CI, $source_data or die $!; - my $len = sysread $CO, $calc_data, $bufsize; -#my $a = bin2hex($source_data); -#my $b = bin2hex($calc_data); -#warn "$a $b"; -#sleep 1; - - #print STDERR "len=$len, bufsize=$bufsize\n"; - die if $len ne $bufsize; - #print STDERR "calc_data=", bin2hex($calc_data), "\n"; - - if ( (!$enc && $ciph =~ /des/) || - $ciph =~ /rc4/ || - $cipher =~ /ecb/ ) { - #TDES in decryption mode, RC4 and ECB mode - #have a special rule - $source_data = $calc_data; - } else { - $source_data = $old_calc_data; - } -#my $c = bin2hex($source_data); -#my $d = bin2hex($calc_data); -#warn "$c $d"; - } - } - close $CO; - close $CI; - waitpid $pid, 0; - - if ($enc) { - $out .= "CIPHERTEXT = ". bin2hex($calc_data). "\n\n"; - } else { - $out .= "PLAINTEXT = ". bin2hex($calc_data). "\n\n"; - } - - if ( $ciph =~ /aes/ ) { - $key1 ^= substr($old_calc_data . $calc_data, -$keylen); - #print STDERR bin2hex($key1)."\n"; - } elsif ( $ciph =~ /des/ ) { - die "Wrong keylen $keylen" if ($keylen != 24); - - # $nkey needed as $key holds the concatenation of the - # old key atm - my $nkey = fix_key_parity(substr($key1,0,8) ^ $calc_data); - #print STDERR "KEY1 = ". bin2hex($nkey)."\n"; - if (substr($key1,0,8) ne substr($key1,8,8)) { - #print STDERR "KEY2 recalc: KEY1==KEY3, KEY2 indep. or all KEYs are indep.\n"; - $key2 = fix_key_parity((substr($key1,8,8) ^ $old_calc_data)); - } else { - #print STDERR "KEY2 recalc: KEY1==KEY2==KEY3\n"; - $key2 = fix_key_parity((substr($key1,8,8) ^ $calc_data)); - } - #print STDERR "KEY2 = ". bin2hex($key2)."\n"; - if ( substr($key1,0,8) eq substr($key1,16)) { - #print STDERR "KEY3 recalc: KEY1==KEY2==KEY3 or KEY1==KEY3, KEY2 indep.\n"; - $key3 = fix_key_parity((substr($key1,16) ^ $calc_data)); - } else { - #print STDERR "KEY3 recalc: all KEYs are independent\n"; - $key3 = fix_key_parity((substr($key1,16) ^ $old_old_calc_data)); - } - #print STDERR "KEY3 = ". bin2hex($key3)."\n"; - - # reset the first key - concardination happens at - # beginning of loop - $key1=$nkey; - } elsif ($ciph =~ /rc4/ ) { - $key1 ^= substr($calc_data, 0, 16); - #print STDERR bin2hex($key1)."\n"; - } else { - die "Test limitation: cipher '$cipher' not supported in Monte Carlo testing"; - } - - if ($cipher =~ /des-ede3-ofb/) { - $source_data = $source_data ^ $next_source; - } elsif (!$enc && $cipher =~ /des-ede3-cfb/) { - #TDES decryption CFB has a special rule - $source_data = $next_source; - } elsif ( $ciph =~ /rc4/ || $cipher eq "des-ede3" || $cipher =~ /ecb/) { - #No resetting of IV as the IV is all zero set initially (i.e. no IV) - $source_data = $calc_data; - } elsif (! $enc && $ciph =~ /des/ ) { - #TDES in decryption mode has a special rule - $iv = $old_calc_data; - $source_data = $calc_data; - } else { - $iv = $calc_data; - $source_data = $old_calc_data; - } - } - - return $out; -} - -# Hash Monte Carlo Testing -# $1: Plaintext in hex form -# $2: hash -# return: string formatted as expected by CAVS -sub hash_mct($$) { - my $pt = shift; - my $cipher = shift; - - my $out = ""; - - $out .= "Seed = $pt\n\n"; - - for (my $j=0; $j<100; ++$j) { - $out .= "COUNT = $j\n"; - my $md0=$pt; - my $md1=$pt; - my $md2=$pt; - for (my $i=0; $i<1000; ++$i) { - #print STDERR "outer loop $j; inner loop $i\n"; - my $mi= $md0 . $md1 . $md2; - $md0=$md1; - $md1=$md2; - $md2 = &$hash($mi, $cipher); - $md2 =~ s/\n//; - } - $out .= "MD = $md2\n\n"; - $pt=$md2; - } - - return $out; -} - -# RSA SigGen test -# $1: Message to be signed in hex form -# $2: Hash algorithm -# $3: file name with RSA key in PEM form -# return: string formatted as expected by CAVS -sub rsa_siggen($$$) { - my $data = shift; - my $cipher = shift; - my $keyfile = shift; - - my $out = ""; - - $out .= "SHAAlg = $cipher\n"; - $out .= "Msg = $data\n"; - $out .= "S = " . &$rsa_sign($data, lc($cipher), $keyfile) . "\n"; - - return $out; -} - -# RSA SigVer test -# $1: Message to be verified in hex form -# $2: Hash algoritm -# $3: Signature of message in hex form -# $4: n of the RSA key in hex in hex form -# $5: e of the RSA key in hex in hex form -# return: string formatted as expected by CAVS -sub rsa_sigver($$$$$) { - my $data = shift; - my $cipher = shift; - my $signature = shift; - my $n = shift; - my $e = shift; - - my $out = ""; - - $out .= "SHAAlg = $cipher\n"; - $out .= "e = $e\n"; - $out .= "Msg = $data\n"; - $out .= "S = $signature\n"; - - # 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 - my $keyfile = "rsa_sigver.tmp.$$"; - gen_pubrsakey($keyfile, $n, $e); - - my $sigfile = "$keyfile.sig"; - open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?"; - print FH hex2bin($signature); - close FH; - - $out .= "Result = " . (&$rsa_verify($data, lc($cipher), $keyfile, $sigfile) ? "P\n" : "F\n"); - - unlink($keyfile); - unlink($sigfile); - - return $out; -} - -# RSA X9.31 key generation test -# $1 modulus size -# $2 e -# $3 xp1 -# $4 xp2 -# $5 Xp -# $6 xq1 -# $7 xq2 -# $8 Xq -# return: string formatted as expected by CAVS -sub rsa_keygen($$$$$$$$) { - my $modulus = shift; - my $e = shift; - my $xp1 = shift; - my $xp2 = shift; - my $Xp = shift; - my $xq1 = shift; - my $xq2 = shift; - my $Xq = shift; - - my $out = ""; - - my $ret = &$rsa_derive($modulus, $e, $xp1, $xp2, $Xp, $xq1, $xq2, $Xq); - - my ($P, $Q, $N, $D) = split(/\n/, $ret); - - $out .= "e = $e\n"; - $out .= "xp1 = $xp1\n"; - $out .= "xp2 = $xp2\n"; - $out .= "Xp = $Xp\n"; - $out .= "p = $P\n"; - $out .= "xq1 = $xq1\n"; - $out .= "xq2 = $xq2\n"; - $out .= "Xq = $Xq\n"; - $out .= "q = $Q\n"; - $out .= "n = $N\n"; - $out .= "d = $D\n\n"; - - return $out; - -} - -# X9.31 RNG test -# $1 key for the AES cipher -# $2 DT value -# $3 V value -# $4 type ("VST", "MCT") -# return: string formatted as expected by CAVS -sub rngx931($$$$) { - my $key=shift; - my $dt=shift; - my $v=shift; - my $type=shift; - - my $out = "Key = $key\n"; - $out .= "DT = $dt\n"; - $out .= "V = $v\n"; - - my $count = 1; - $count = 10000 if ($type eq "MCT"); - - my $rnd_val = ""; - - # we read 16 bytes from RNG - my $bufsize = 16; - - my ($CO, $CI); - my $rng_imp = &$state_rng($key, $dt, $v); - my $pid = open2($CO, $CI, $rng_imp); - for (my $i = 0; $i < $count; ++$i) { - my $len = sysread $CO, $rnd_val, $bufsize; - #print STDERR "len=$len, bufsize=$bufsize\n"; - die "len=$len != bufsize=$bufsize" if $len ne $bufsize; - #print STDERR "calc_data=", bin2hex($rnd_val), "\n"; - } - close $CO; - close $CI; - waitpid $pid, 0; - - $out .= "R = " . bin2hex($rnd_val) . "\n\n"; - - return $out; -} - -sub drbg_kat($$$$$$$$$) { - my $cipher = shift; - my $drbg_expectedlen = shift; - my $drbg_entropy = shift; - my $drbg_nonce = shift; - my $drbg_pers = shift; - my $drbg_addtla = shift; - my $drbg_addtlb = shift; - my $drbg_entpra = shift; - my $drbg_entprb = shift; - my $out = ""; - - my $ret = &$drbg($cipher, $drbg_expectedlen, $drbg_entropy, - $drbg_nonce, $drbg_pers, $drbg_addtla, - $drbg_addtlb, $drbg_entpra, $drbg_entprb); - $out = "ReturnedBits = " . $ret . "\n"; - return $out; -} - -# DSA PQGen test -# $1 modulus size -# $2 q size -# $3 number of rounds to perform the test -# return: string formatted as expected by CAVS -sub dsa_pqgen_driver($$$) { - my $mod = shift; - my $qsize = shift; - my $rounds = shift; - - my $out = ""; - for(my $i=0; $i<$rounds; $i++) { - my $ret = &$dsa_pqggen($mod, $qsize, ""); - my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); - die "Return value does not contain all expected values of P, Q, Seed, c for dsa_pqggen" - if (!defined($P) || !defined($Q) || - !defined($Seed) || !defined($c)); - - # now change the counter to decimal as CAVS wants decimal - # counter value although all other is HEX - $c = hex($c); - - $out .= "P = $P\n"; - $out .= "Q = $Q\n"; - $out .= "domain_parameter_seed = $Seed\n"; - $out .= "counter = $c\n\n"; - } - - return $out; -} - -# DSA GGen test -# $1 modulus size -# $2 q size -# $3 p in hex form -# $4 q in hex form -# return: string formatted as expected by CAVS -sub dsa_ggen_driver($$$$) { - my $mod = shift; - my $qsize = shift; - my $p = shift; - my $q = shift; - - my $out = ""; - my $ret = &$dsa_ggen($mod, $qsize, $p, $q); - my ($P, $Q, $G) = split(/\n/, $ret); - die "Return value does not contain all expected values of P, Q, G for dsa_ggen" - if (!defined($P) || !defined($Q) || !defined($G)); - - $out .= "G = $G\n\n"; - - return $out; -} - -# DSA PQVer test -# $1 modulus size -# $2 q size -# $3 p in hex form -# $4 q in hex form -# $5 seed in hex form -# $6 c decimal counter -# return: string formatted as expected by CAVS -sub dsa_pqver_driver($$$$$$) { - my $mod = shift; - my $qsize = shift; - my $p = shift; - my $q = shift; - my $seed = shift; - my $c = shift; - - my $out = ""; - my $ret = &$dsa_pqggen($mod, $qsize, $seed); - my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); - die "Return value does not contain all expected values of P, Q, G, seed, c for dsa_pqggen" - if (!defined($P) || !defined($Q) || !defined($G) || - !defined($seed2) || !defined($c2)); - - $c2 = hex($c2); - - $out .= "Seed = $seed\n"; - $out .= "c = $c\n"; - - if ($P eq $p && $Q eq $q && $seed eq lc $seed2 && $c eq $c2) { - $out .= "Result = P\n\n"; - } - else { - $out .= "Result = F\n\n"; - } - return $out; -} - -sub hexcomp($$) { - my $a = lc shift; - my $b = lc shift; - - if (length $a < length $b) { - my $c = $a; - $a = $b; - $b = $a; - } - while (length $b < length $a) { - $b = "00$b"; - } - - return $a eq $b; -} - -# DSA PQGVer test -# $1 modulus size -# $2 q size -# $3 p in hex form -# $4 q in hex form -# $5 g in hex form -# $6 seed in hex form -# $7 c decimal counter -# $8 h in hex form -# return: string formatted as expected by CAVS -sub dsa_pqgver_driver($$$$$$$$) { - my $mod = shift; - my $qsize = shift; - my $p = shift; - my $q = shift; - my $g = shift; - my $seed = shift; - my $c = shift; - my $h = shift; - - my $out = ""; - my $ret = &$dsa_pqggen($mod, $qsize, $seed); - my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); - die "Return value does not contain all expected values of P, Q, G, seed, c, H for dsa_pqggen" - if (!defined($P) || !defined($Q) || !defined($G) || - !defined($seed2) || !defined($c2) || !defined($h2)); - - - - $out .= "Seed = $seed\n"; - $out .= "c = $c\n"; - $out .= "H = $h\n"; - - $c2 = hex($c2); - - if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($G, $g) && hexcomp($seed, $seed2) && - $c == $c2 && hex($h) == hex($h2)) { - $out .= "Result = P\n\n"; - } - else { - $out .= "Result = F\n\n"; - } - - return $out; -} - -# DSA Keypair test -# $1 modulus size -# $2 q size -# $3 number of rounds to perform the test -# return: string formatted as expected by CAVS -sub dsa_keypair_driver($$$) { - my $mod = shift; - my $qsize = shift; - my $rounds = shift; - - my $out = ""; - my $tmpkeyfile = "dsa_siggen.tmp.$$"; - my %pqg = &$gen_dsakey($mod, $qsize, $tmpkeyfile); - $out .= "P = " . $pqg{'P'} . "\n"; - $out .= "Q = " . $pqg{'Q'} . "\n"; - $out .= "G = " . $pqg{'G'} . "\n\n"; - unlink($tmpkeyfile); - - for(my $i=0; $i<$rounds; $i++) { - my $ret = &$gen_dsakey_domain($pqg{'P'}, $pqg{'Q'}, $pqg{'G'}); - my ($X, $Y) = split(/\n/, $ret); - die "Return value does not contain all expected values of X, Y for gen_dsakey_domain" - if (!defined($X) || !defined($Y)); - - $out .= "X = $X\n"; - $out .= "Y = $Y\n\n"; - } - - return $out; -} - -# DSA SigGen test -# $1: Message to be signed in hex form -# $2: file name with DSA key in PEM form -# return: string formatted as expected by CAVS -sub dsa_siggen($$) { - my $data = shift; - my $keyfile = shift; - - my $out = ""; - - my %ret = &$dsa_sign($data, $keyfile); - - $out .= "Msg = $data\n"; - $out .= "Y = " . $ret{'Y'} . "\n"; - $out .= "R = " . $ret{'R'} . "\n"; - $out .= "S = " . $ret{'S'} . "\n"; - - return $out; -} - - -# DSA signature verification -# $1 modulus -# $2 P -# $3 Q -# $4 G -# $5 Y - public key -# $6 r -# $7 s -# $8 message to be verified -# return: string formatted as expected by CAVS -sub dsa_sigver($$$$$$$$) { - my $modulus = shift; - my $p = shift; - my $q = shift; - my $g = shift; - my $y = shift; - my $r = shift; - my $s = shift; - my $msg = shift; - - my $out = ""; - - #PQG are already printed - do not print them here - - $out .= "Msg = $msg\n"; - $out .= "Y = $y\n"; - $out .= "R = $r\n"; - $out .= "S = $s\n"; - - # 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 - my $keyfile = "dsa_sigver.tmp.$$"; - &$dsa_genpubkey($keyfile, $p, $q, $g, $y); - - $out .= "Result = " . (&$dsa_verify($msg, $keyfile, $r, $s) ? "P\n" : "F\n"); - - unlink($keyfile); - - return $out; -} - -############################################################## -# Parser of input file and generator of result file -# - -sub usage() { - - print STDERR "Usage: -$0 [-R] [-D] [-I name] - --R execution of ARCFOUR instead of OpenSSL --I NAME Use interface style NAME: - openssl OpenSSL (default) - libgcrypt Libgcrypt - cryptoapi Kernel --D SigGen and SigVer are executed with DSA - Please note that the DSA CAVS vectors do not allow distinguishing - them from the RSA vectors. As the RSA test is the default, you have - to supply this option to apply the DSA logic"; -} - -# Parser of CAVS test vector file -# $1: Test vector file -# $2: Output file for test results -# return: nothing -sub parse($$) { - my $infile = shift; - my $outfile = shift; - - my $out = ""; - - # this is my cipher/hash type - my $cipher = ""; - - # Test type - # 1 - cipher known answer test - # 2 - cipher Monte Carlo test - # 3 - hash known answer test - # 4 - hash Monte Carlo test - # 5 - RSA signature generation - # 6 - RSA signature verification - my $tt = 0; - - # Variables for tests - my $keytype = ""; # we can have "KEY", "KEYs", "KEY1" - my $key1 = ""; - my $key2 = undef; #undef needed for allowing - my $key3 = undef; #the use of them as input variables - my $pt = ""; - my $enc = 1; - my $iv = ""; - my $len = undef; #see key2|3 - my $n = ""; - my $e = ""; - my $signature = ""; - my $rsa_keyfile = ""; - my $dsa_keyfile = ""; - my $dt = ""; - my $v = ""; - my $klen = ""; - my $tlen = ""; - my $modulus = ""; - my $qsize = ""; - my $capital_n = 0; - my $num = 0; - my $capital_p = ""; - my $capital_q = ""; - my $capital_g = ""; - my $capital_y = ""; - my $capital_r = ""; - my $capital_h = ""; - my $c = ""; - my $xp1 = ""; - my $xp2 = ""; - my $Xp = ""; - my $xq1 = ""; - my $xq2 = ""; - my $Xq = ""; - my $drbg_expectedlen = ""; - my $drbg_entropy = ""; - my $drbg_nonce = ""; - my $drbg_pers = ""; - my $drbg_addtla = ""; - my $drbg_addtlb = ""; - my $drbg_entpra = ""; - my $drbg_entprb = ""; - - my $mode = ""; - - open(IN, "<$infile"); - while() { - - my $line = $_; - chomp($line); - $line =~ s/\r//; - - my $keylen = ""; - - # Mode and type check - # consider the following parsed line - # '# AESVS MCT test data for CBC' - # '# TDES Multi block Message Test for CBC' - # '# INVERSE PERMUTATION - KAT for CBC' - # '# SUBSTITUTION TABLE - KAT for CBC' - # '# TDES Monte Carlo (Modes) Test for CBC' - # '# "SHA-1 Monte" information for "IBMRHEL5"' - # '# "SigVer PKCS#1 Ver 1.5" information for "IBMRHEL5"' - # '# "SigGen PKCS#1 Ver 1.5" information for "IBMRHEL5"' - # '#RC4VS MCT test data' - - # avoid false positives from user specified 'for "PRODUCT"' strings - my $tmpline = $line; - $tmpline =~ s/ for ".*"//; - - ##### 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|KeyPair|PQGVer|DRBG)/) { - if ($tmpline =~ /CBC/) { $mode="cbc"; } - elsif ($tmpline =~ /ECB/) { $mode="ecb"; } - elsif ($tmpline =~ /OFB/) { $mode="ofb"; } - elsif ($tmpline =~ /CFB/) { $mode="cfb"; } - #we do not need mode as the cipher is already clear - elsif ($tmpline =~ /SHA-1/) { $cipher="sha1"; } - elsif ($tmpline =~ /SHA-224/) { $cipher="sha224"; } - elsif ($tmpline =~ /SHA-256/) { $cipher="sha256"; } - elsif ($tmpline =~ /SHA-384/) { $cipher="sha384"; } - elsif ($tmpline =~ /SHA-512/) { $cipher="sha512"; } - #we do not need mode as the cipher is already clear - elsif ($tmpline =~ /RC4VS/) { $cipher="rc4"; } - elsif ($tmpline =~ /SigGen|SigVer/) { - die "Error: X9.31 is not supported" - if ($tmpline =~ /X9/); - $cipher="sha1"; #place holder - might be overwritten later - } - - if ($tmpline =~ /^#.*AESVS/) { - # AES cipher (part of it) - $cipher="aes"; - } - if ($tmpline =~ /^#.*(TDES|KAT)/) { - # TDES cipher (full definition) - # the FIPS-140 test generator tool does not produce - # machine readable output! - if ($mode eq "cbc") { $cipher="des-ede3-cbc"; } - if ($mode eq "ecb") { $cipher="des-ede3"; } - if ($mode eq "ofb") { $cipher="des-ede3-ofb"; } - if ($mode eq "cfb") { $cipher="des-ede3-cfb"; } - } - - # check for RNG - if ($tmpline =~ /ANSI X9\.31/) { - # change the tmpline to add the type of the - # test which is ONLY visible from the file - # name :-( - if ($infile =~ /MCT\.req/) { - $tmpline .= " MCT"; - } elsif ($infile =~ /VST\.req/) { - $tmpline .= " VST"; - } else { - die "Unexpected cipher type with $infile"; - } - } - - if ($tt == 0) { - ##### Identify the test type - if ($tmpline =~ /DRBG/) { - $tt = 18; - die "Interface function for SP800-90A DRBG testing not defined for tested library" - if (!defined($drbg)); - } elsif ($tmpline =~ /PQGVer/) { - $tt = 16; - die "Interface function for DSA PQGVer testing not defined for tested library" - if (!defined($dsa_pqggen)); - } elsif ($tmpline =~ /KeyPair/) { - $tt = 14; - die "Interface function dsa_keygen for DSA key generation not defined for tested library" - if (!defined($gen_dsakey_domain)); - } elsif ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { - $tt = 13; - die "Interface function rsa_derive for RSA key generation not defined for tested library" - if (!defined($rsa_derive)); - } elsif ($tmpline =~ /SigVer/ && $opt{'D'} ) { - $tt = 12; - die "Interface function dsa_verify or dsa_genpubkey for DSA verification not defined for tested library" - if (!defined($dsa_verify) || !defined($dsa_genpubkey)); - } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { - $tt = 11; - die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" - if (!defined($dsa_sign) || !defined($gen_dsakey)); - } elsif ($tmpline =~ /PQGGen/) { - $tt = 10; - die "Interface function for DSA PQGGen testing not defined for tested library" - if (!defined($dsa_pqggen) || !defined($dsa_ggen)); - } elsif ($tmpline =~ /Hash sizes tested/) { - $tt = 9; - die "Interface function hmac for HMAC testing not defined for tested library" - if (!defined($hmac)); - } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /MCT/) { - $tt = 8; - die "Interface function state_rng for RNG MCT not defined for tested library" - if (!defined($state_rng)); - } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /VST/) { - $tt = 7; - die "Interface function state_rng for RNG KAT not defined for tested library" - if (!defined($state_rng)); - } elsif ($tmpline =~ /SigVer/ ) { - $tt = 6; - die "Interface function rsa_verify or gen_rsakey for RSA verification not defined for tested library" - if (!defined($rsa_verify) || !defined($gen_rsakey)); - } elsif ($tmpline =~ /SigGen/ ) { - $tt = 5; - die "Interface function rsa_sign or gen_rsakey for RSA sign not defined for tested library" - if (!defined($rsa_sign) || !defined($gen_rsakey)); - } elsif ($tmpline =~ /Monte|MCT|Carlo/ && $cipher =~ /^sha/) { - $tt = 4; - die "Interface function hash for Hashing not defined for tested library" - if (!defined($hash)); - } elsif ($tmpline =~ /Monte|MCT|Carlo/) { - $tt = 2; - die "Interface function state_cipher for Stateful Cipher operation defined for tested library" - if (!defined($state_cipher) && !defined($state_cipher_des)); - } elsif ($cipher =~ /^sha/) { - $tt = 3; - die "Interface function hash for Hashing not defined for tested library" - if (!defined($hash)); - } else { - $tt = 1; - die "Interface function encdec for Encryption/Decryption not defined for tested library" - if (!defined($encdec)); - } - } - } - - # This is needed as ARCFOUR does not operate with an IV - $iv = "00000000000000000000000000000000" if ($cipher eq "rc4" - && $iv eq "" ); - - # we are now looking for the string - # '# Key Length : 256' - # found in AES - if ($tmpline =~ /^# Key Length.*?(128|192|256)/) { - if ($cipher eq "aes") { - $cipher="$cipher-$1-$mode"; - } else { - die "Error: Key length $1 given for cipher $cipher which is unexpected"; - } - } - - # Get the test data - if ($line =~ /^(KEY|KEY1|Key)\s*=\s*(.*)/) { # found in ciphers and RNG - die "KEY seen twice - input file crap" if ($key1 ne ""); - $keytype=$1; - $key1=$2; - $key1 =~ s/\s//g; #replace potential white spaces - } - elsif ($line =~ /^(KEYs)\s*=\s*(.*)/) { # found in ciphers and RNG - die "KEY seen twice - input file crap" if ($key1 ne ""); - $keytype=$1; - $key1=$2; - $key1 =~ s/\s//g; #replace potential white spaces - $key2 = $key1; - $key3 = $key1; - } - elsif ($line =~ /^KEY2\s*=\s*(.*)/) { # found in TDES - die "First key not set, but got already second key - input file crap" if ($key1 eq ""); - die "KEY2 seen twice - input file crap" if (defined($key2)); - $key2=$1; - $key2 =~ s/\s//g; #replace potential white spaces - } - elsif ($line =~ /^KEY3\s*=\s*(.*)/) { # found in TDES - die "Second key not set, but got already third key - input file crap" if ($key2 eq ""); - die "KEY3 seen twice - input file crap" if (defined($key3)); - $key3=$1; - $key3 =~ s/\s//g; #replace potential white spaces - } - elsif ($line =~ /^IV\s*=\s*(.*)/) { # found in ciphers - die "IV seen twice - input file crap" if ($iv ne ""); - $iv=$1; - $iv =~ s/\s//g; #replace potential white spaces - } - elsif ($line =~ /^PLAINTEXT\s*=\s*(.*)/) { # found in ciphers - if ( $1 !~ /\?/ ) { #only use it if there is valid hex data - die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne ""); - $pt=$1; - $pt =~ s/\s//g; #replace potential white spaces - $enc=1; - } - } - elsif ($line =~ /^CIPHERTEXT\s*=\s*(.*)/) { # found in ciphers - if ( $1 !~ /\?/ ) { #only use it if there is valid hex data - die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne ""); - $pt=$1; - $pt =~ s/\s//g; #replace potential white spaces - $enc=0; - } - } - elsif ($line =~ /^Len\s*=\s*(.*)/) { # found in hashs - $len=$1; - } - elsif ($line =~ /^(Msg|Seed)\s*=\s*(.*)/) { # found in hashs - die "Msg/Seed seen twice - input file crap" if ($pt ne ""); - $pt=$2; - } - elsif ($line =~ /^\[A.2.1\s.*\]$/) { # found in DSA2 PQGGen request - $out .= $line . "\n"; # print it - if ($tt == 10) { - # now generate G from PQ - $tt = 15; - } - } - elsif ($line =~ /^\[A.2.2\s.*\]$/) { # found in DSA2 PQGVer request - $out .= $line . "\n"; # print it - if ($tt == 16) { - # now verify PQG - $tt = 17; - } - } - elsif ($line =~ /^\[mod\s*=\s*L=([0-9]*),\s*N=([0-9]*).*\]$/) { # found in DSA2 requests - $modulus = $1; - $qsize = $2; - $out .= $line . "\n\n"; # print it - # clear eventual PQG - $capital_p = ""; - $capital_q = ""; - $capital_g = ""; - # generate the private key with given bit length now - # as we have the required key length in bit - if ($tt == 11) { - $dsa_keyfile = "dsa_siggen.tmp.$$"; - my %pqg = &$gen_dsakey($modulus, $qsize, $dsa_keyfile); - $out .= "P = " . $pqg{'P'} . "\n"; - $out .= "Q = " . $pqg{'Q'} . "\n"; - $out .= "G = " . $pqg{'G'} . "\n\n"; - } - } - elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests - $modulus = $1; - $out .= $line . "\n\n"; # print it - # generate the private key with given bit length now - # as we have the required key length in bit - if ( $tt == 5 ) { - # XXX maybe a secure temp file name is better here - # but since it is not run on a security sensitive - # system, I hope that this is fine - $rsa_keyfile = "rsa_siggen.tmp.$$"; - &$gen_rsakey($modulus, $rsa_keyfile); - my $modulus = pipe_through_program("", "openssl rsa -pubout -modulus -in $rsa_keyfile"); - $modulus =~ s/Modulus=(.*?)\s(.|\s)*/$1/; - $out .= "n = $modulus\n"; - $out .= "\ne = 10001\n" - } - } - elsif ($line =~ /^SHAAlg\s*=\s*(.*)/) { #found in RSA requests - $cipher=$1; - } - elsif($line =~ /^n\s*=\s*(.*)/) { # found in RSA requests - $out .= $line . "\n"; - $n=$1; - } - elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests - $e=$1; - } - elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests - die "S seen twice - input file crap" if ($signature ne ""); - $signature=$1; - } - elsif ($line =~ /^DT\s*=\s*(.*)/) { # X9.31 RNG requests - die "DT seen twice - check input file" - if ($dt ne ""); - $dt=$1; - } - elsif ($line =~ /^V\s*=\s*(.*)/) { # X9.31 RNG requests - die "V seen twice - check input file" - if ($v ne ""); - $v=$1; - } - elsif ($line =~ /^Klen\s*=\s*(.*)/) { # HMAC requests - die "Klen seen twice - check input file" - if ($klen ne ""); - $klen=$1; - } - elsif ($line =~ /^Tlen\s*=\s*(.*)/) { # HMAC RNG requests - die "Tlen seen twice - check input file" - if ($tlen ne ""); - $tlen=$1; - } - elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair - die "N seen twice - check input file" - if ($capital_n); - $capital_n = $1; - } - elsif ($line =~ /^Num\s*=\s*(.*)/) { #DSA PQGGen - die "Num seen twice - check input file" - if ($num); - $num = $1; - } - elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer - die "P seen twice - check input file" - if ($capital_p); - $capital_p = $1; - $out .= $line . "\n"; # print it - } - elsif ($line =~ /^Q\s*=\s*(.*)/) { #DSA SigVer - die "Q seen twice - check input file" - if ($capital_q); - $capital_q = $1; - $out .= $line . "\n"; # print it - } - elsif ($line =~ /^G\s*=\s*(.*)/) { #DSA SigVer - die "G seen twice - check input file" - if ($capital_g); - $capital_g = $1; - $out .= $line . "\n"; # print it - } - elsif ($line =~ /^Y\s*=\s*(.*)/) { #DSA SigVer - die "Y seen twice - check input file" - if ($capital_y); - $capital_y = $1; - } - elsif ($line =~ /^R\s*=\s*(.*)/) { #DSA SigVer - die "R seen twice - check input file" - if ($capital_r); - $capital_r = $1; - } - elsif ($line =~ /^H\s*=\s*(.*)/) { #DSA PQGVer - die "H seen twice - check input file" - if ($capital_h); - $capital_h = $1; - } - elsif ($line =~ /^c\s*=\s*(.*)/) { #DSA PQGVer - die "c seen twice - check input file" - if ($c); - $c = $1; - } - elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen - die "xp1 seen twice - check input file" - if ($xp1); - $xp1 = $1; - } - elsif ($line =~ /^xp2\s*=\s*(.*)/) { #RSA key gen - die "xp2 seen twice - check input file" - if ($xp2); - $xp2 = $1; - } - elsif ($line =~ /^Xp\s*=\s*(.*)/) { #RSA key gen - die "Xp seen twice - check input file" - if ($Xp); - $Xp = $1; - } - elsif ($line =~ /^xq1\s*=\s*(.*)/) { #RSA key gen - die "xq1 seen twice - check input file" - if ($xq1); - $xq1 = $1; - } - elsif ($line =~ /^xq2\s*=\s*(.*)/) { #RSA key gen - die "xq2 seen twice - check input file" - if ($xq2); - $xq2 = $1; - } - elsif ($line =~ /^Xq\s*=\s*(.*)/) { #RSA key gen - die "Xq seen twice - check input file" - if ($Xq); - $Xq = $1; - } - # DRBG types - elsif ($line =~ /^\[SHA-1\]/) { $cipher="sha1"; $out .= $line . "\n";} - elsif ($line =~ /^\[SHA-224\]/) { $cipher="sha224"; $out .= $line . "\n";} - elsif ($line =~ /^\[SHA-256\]/) { $cipher="sha256"; $out .= $line . "\n";} - elsif ($line =~ /^\[SHA-384\]/) { $cipher="sha384"; $out .= $line . "\n";} - elsif ($line =~ /^\[SHA-512\]/) { $cipher="sha512"; $out .= $line . "\n";} - elsif ($line =~ /^\[AES-128/) { $cipher="aes128"; $out .= $line . "\n";} - elsif ($line =~ /^\[AES-192/) { $cipher="aes192"; $out .= $line . "\n";} - elsif ($line =~ /^\[AES-256/) { $cipher="aes256"; $out .= $line . "\n";} - elsif ($line =~ /^\[ReturnedBitsLen\s*=\s*(.*)]/) { $drbg_expectedlen = $1; $out .= $line . "\n";} - elsif ($line =~ /^EntropyInput\s*=\s*(.*)/) { $drbg_entropy=$1; $out .= $line . "\n";} - elsif ($line =~ /^Nonce\s*=\s*(.*)/) { $drbg_nonce=$1; $out .= $line . "\n";} - elsif ($line =~ /^PersonalizationString\s*=\s*(.*)/) { - $drbg_pers=$1; - if ($drbg_pers eq "") { - $drbg_pers = "z"; - } - $out .= $line . "\n"; - } - elsif ($line =~ /^AdditionalInput\s*=\s*(.*)/) { - if ($drbg_addtla eq "") { - $drbg_addtla=$1; - if ($drbg_addtla eq "") { - $drbg_addtla = "z"; - } - } else { - $drbg_addtlb=$1; - if ($drbg_addtlb eq "") { - $drbg_addtlb = "z"; - } - } - $out .= $line . "\n"; - } - elsif ($line =~ /^EntropyInputPR\s*=\s*(.*)/) { - if ($drbg_entpra eq "") { - $drbg_entpra=$1; - if ($drbg_entpra eq "") { - $drbg_entpra = "z"; - } - } else { - $drbg_entprb=$1; - if ($drbg_entprb eq "") { - $drbg_entprb = "z"; - } - } - $out .= $line . "\n"; - } - else { - $out .= $line . "\n"; - } - - # call tests if all input data is there - if ($tt == 1) { - if ($key1 ne "" && $pt ne "" && $cipher ne "") { - $out .= kat($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc); - $keytype = ""; - $key1 = ""; - $key2 = undef; - $key3 = undef; - $iv = ""; - $pt = ""; - } - } - elsif ($tt == 2) { - if ($key1 ne "" && $pt ne "" && $cipher ne "") { - $out .= crypto_mct($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc); - $keytype = ""; - $key1 = ""; - $key2 = undef; - $key3 = undef; - $iv = ""; - $pt = ""; - } - } - elsif ($tt == 3) { - if ($pt ne "" && $cipher ne "") { - $out .= hash_kat($pt, $cipher, $len); - $pt = ""; - $len = undef; - } - } - elsif ($tt == 4) { - if ($pt ne "" && $cipher ne "") { - $out .= hash_mct($pt, $cipher); - $pt = ""; - } - } - elsif ($tt == 5) { - if ($pt ne "" && $cipher ne "" && $rsa_keyfile ne "") { - $out .= rsa_siggen($pt, $cipher, $rsa_keyfile); - $pt = ""; - } - } - elsif ($tt == 6) { - if ($pt ne "" && $cipher ne "" && $signature ne "" && $n ne "" && $e ne "") { - $out .= rsa_sigver($pt, $cipher, $signature, $n, $e); - $pt = ""; - $signature = ""; - } - } - elsif ($tt == 7 ) { - if ($key1 ne "" && $dt ne "" && $v ne "") { - $out .= rngx931($key1, $dt, $v, "VST"); - $key1 = ""; - $dt = ""; - $v = ""; - } - } - elsif ($tt == 8 ) { - if ($key1 ne "" && $dt ne "" && $v ne "") { - $out .= rngx931($key1, $dt, $v, "MCT"); - $key1 = ""; - $dt = ""; - $v = ""; - } - } - elsif ($tt == 9) { - if ($klen ne "" && $tlen ne "" && $key1 ne "" && $pt ne "") { - $out .= hmac_kat($klen, $tlen, $key1, $pt); - $key1 = ""; - $tlen = ""; - $klen = ""; - $pt = ""; - } - } - elsif ($tt == 10) { - if ($modulus ne "" && $qsize ne "" && $num > 0) { - $out .= dsa_pqgen_driver($modulus, $qsize, $num); - $num = 0; - } - } - elsif ($tt == 11) { - if ($pt ne "" && $dsa_keyfile ne "") { - $out .= dsa_siggen($pt, $dsa_keyfile); - $pt = ""; - } - } - elsif ($tt == 12) { - if ($modulus ne "" && - $capital_p ne "" && - $capital_q ne "" && - $capital_g ne "" && - $capital_y ne "" && - $capital_r ne "" && - $signature ne "" && - $pt ne "") { - $out .= dsa_sigver($modulus, - $capital_p, - $capital_q, - $capital_g, - $capital_y, - $capital_r, - $signature, - $pt); - - # We do not clear the domain values PQG and - # the modulus value as they - # are specified only once in a file - # and we do not need to print them as they - # are already printed above - $capital_y = ""; - $capital_r = ""; - $signature = ""; - $pt = ""; - } - } - elsif ($tt == 13) { - if($modulus ne "" && - $e ne "" && - $xp1 ne "" && - $xp2 ne "" && - $Xp ne "" && - $xq1 ne "" && - $xq2 ne "" && - $Xq ne "") { - $out .= rsa_keygen($modulus, - $e, - $xp1, - $xp2, - $Xp, - $xq1, - $xq2, - $Xq); - $e = ""; - $xp1 = ""; - $xp2 = ""; - $Xp = ""; - $xq1 = ""; - $xq2 = ""; - $Xq = ""; - } - } - elsif ($tt == 14) { - if ($modulus ne "" && - $qsize ne "" && - $capital_n > 0) { - $out .= dsa_keypair_driver($modulus, - $qsize, - $capital_n); - $capital_n = 0; - } - } - elsif ($tt == 15) { - if ($modulus ne "" && - $qsize ne "" && - $capital_p ne "" && - $capital_q ne "") { - $out .= dsa_ggen_driver($modulus, - $qsize, - $capital_p, - $capital_q); - $capital_p = ""; - $capital_q = ""; - $num--; - } - } - elsif ($tt == 16) { - if ($modulus ne "" && - $qsize ne "" && - $capital_p ne "" && - $capital_q ne "" && - $pt ne "" && - $c ne "") { - $out .= dsa_pqver_driver($modulus, - $qsize, - $capital_p, - $capital_q, - $pt, - $c); - $capital_p = ""; - $capital_q = ""; - $pt = ""; - $c = ""; - } - } - elsif ($tt == 17) { - if ($modulus ne "" && - $qsize ne "" && - $capital_p ne "" && - $capital_q ne "" && - $capital_g ne "" && - $pt ne "" && - $c ne "" && - $capital_h ne "") { - $out .= dsa_pqgver_driver($modulus, - $qsize, - $capital_p, - $capital_q, - $capital_g, - $pt, - $c, - $capital_h); - $capital_p = ""; - $capital_q = ""; - $capital_g = ""; - $pt = ""; - $c = ""; - $capital_h = ""; - } - } - elsif ($tt == 18) { - if ($cipher ne "" && - $drbg_expectedlen ne "" && - $drbg_entropy ne "" && - $drbg_nonce ne "" && - $drbg_pers ne "" && - $drbg_addtla ne "" && - $drbg_addtlb ne "") { - if ($drbg_entpra ne "" && $drbg_entprb eq "") { - next; - } - my $tmpcipher = $cipher; - if ($infile =~ /HMAC_DRBG\.req/) { - $tmpcipher = "hmac $tmpcipher"; - } elsif ($infile =~ /Hash_DRBG\.req/) { - $tmpcipher = "hash $tmpcipher"; - } elsif ($infile =~ /CTR_DRBG\.req/) { - $tmpcipher = "ctr $tmpcipher"; - } else { - die "unknown DRBG input file $infile"; - } - $out .= drbg_kat($tmpcipher, $drbg_expectedlen, - $drbg_entropy, $drbg_nonce, - $drbg_pers, $drbg_addtla, - $drbg_addtlb, $drbg_entpra, - $drbg_entprb); - $drbg_entropy = ""; - $drbg_nonce = ""; - $drbg_pers = ""; - $drbg_addtla = ""; - $drbg_addtlb = ""; - $drbg_entpra = ""; - $drbg_entprb = ""; - } - } - elsif ($tt > 0) { - die "Test case $tt not defined"; - } - } - - close IN; - $out =~ s/\n/\r\n/g; # make it a dos file - open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?"; - print OUT $out; - close OUT; - -} - -# Signalhandler -sub cleanup() { - unlink("rsa_siggen.tmp.$$"); - unlink("rsa_sigver.tmp.$$"); - unlink("rsa_sigver.tmp.$$.sig"); - unlink("rsa_sigver.tmp.$$.der"); - unlink("rsa_sigver.tmp.$$.cnf"); - unlink("dsa_siggen.tmp.$$"); - unlink("dsa_sigver.tmp.$$"); - unlink("dsa_sigver.tmp.$$.sig"); - exit; -} - -############################################################ -# -# let us pretend to be C :-) -sub main() { - - usage() unless @ARGV; - - getopts("DRI:", \%opt) or die "bad option"; - - ##### Set library - - if ( ! defined $opt{'I'} || $opt{'I'} eq 'libgcrypt' ) { - print STDERR "Using libgcrypt interface functions\n"; - $encdec = \&libgcrypt_encdec; - $rsa_sign = \&libgcrypt_rsa_sign; - $rsa_verify = \&libgcrypt_rsa_verify; - $gen_rsakey = \&libgcrypt_gen_rsakey; - $rsa_derive = \&libgcrypt_rsa_derive; - $hash = \&libgcrypt_hash; - $state_cipher = \&libgcrypt_state_cipher; - $state_cipher_des = \&libgcrypt_state_cipher_des; - $state_rng = \&libgcrypt_state_rng; - $hmac = \&libgcrypt_hmac; - $dsa_pqggen = \&libgcrypt_dsa_pqggen; - $dsa_ggen = \&libgcrypt_dsa_ggen; - $gen_dsakey = \&libgcrypt_gen_dsakey; - $gen_dsakey_domain = \&libgcrypt_gen_dsakey_domain; - $dsa_sign = \&libgcrypt_dsa_sign; - $dsa_verify = \&libgcrypt_dsa_verify; - $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; - $drbg = \&libgcrypt_drbg; - } elsif ( $opt{'I'} eq 'openssl' ) { - print STDERR "Using OpenSSL interface functions\n"; - $encdec = \&openssl_encdec; - $rsa_sign = \&openssl_rsa_sign; - $rsa_verify = \&openssl_rsa_verify; - $gen_rsakey = \&openssl_gen_rsakey; - $hash = \&openssl_hash; - $state_cipher = \&openssl_state_cipher; - } elsif ( $opt{'I'} eq 'cryptoapi' ) { - print STDERR "Using cryptoapi interface functions\n"; - $encdec = \&cryptoapi_encdec; - $hash = \&cryptoapi_hash; - $state_cipher = \&cryptoapi_state_cipher; - $hmac = \&cryptoapi_hmac; - $state_rng = \&cryptoapi_state_rng; - $drbg = \&cryptoapi_drbg; - } else { - die "Invalid interface option given"; - } - - my $infile=$ARGV[0]; - die "Error: Test vector file $infile not found" if (! -f $infile); - - my $outfile = $infile; - # let us add .rsp regardless whether we could strip .req - $outfile =~ s/\.req$//; - if ($opt{'R'}) { - $outfile .= ".rc4"; - } else { - $outfile .= ".rsp"; - } - if (-f $outfile) { - die "Output file $outfile could not be removed: $?" - unless unlink($outfile); - } - print STDERR "Performing tests from source file $infile with results stored in destination file $outfile\n"; - - #Signal handler - $SIG{HUP} = \&cleanup; - $SIG{INT} = \&cleanup; - $SIG{QUIT} = \&cleanup; - $SIG{TERM} = \&cleanup; - - # Do the job - parse($infile, $outfile); - - cleanup(); - -} - -########################################### -# Call it -main(); -1; diff --git a/drbg_test.patch b/drbg_test.patch deleted file mode 100644 index b644abe..0000000 --- a/drbg_test.patch +++ /dev/null @@ -1,1371 +0,0 @@ -Index: libgcrypt-1.9.0/tests/drbg_test.c -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.0/tests/drbg_test.c -@@ -0,0 +1,1332 @@ -+/* DRBG test for libgcrypt -+ Copyright (C) 2014 Stephan Mueller -+ -+ Compile: -+ gcc -g -I/home/sm/hacking/sources/libs/include -L/home/sm/hacking/sources/libs/lib -o drbg_test drbg_test.c -lgcrypt -lpthread -+ -+ Execute: -+ LD_LIBRARY_PATH=/home/sm/hacking/sources/libs/lib/ ./drbg_test -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "gcrypt.h" -+ -+/* The following definitions are taken verbatim from random/random-drbg.c. -+ * libgcrypt upstream removed the public apis from gcrypt.h in -+ * http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commit;h=fd13372fa9069d3a72947ea59c57e33637c936bf -+ */ -+/****************************************************************** -+ * Constants -+ ******************************************************************/ -+ -+/* -+ * 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 DRBG_PREDICTION_RESIST ((u32)1<<28) -+ -+/* CTR type modifiers (A.1)*/ -+#define DRBG_CTRAES ((u32)1<<0) -+#define DRBG_CTRSERPENT ((u32)1<<1) -+#define DRBG_CTRTWOFISH ((u32)1<<2) -+#define DRBG_CTR_MASK (DRBG_CTRAES | DRBG_CTRSERPENT \ -+ | DRBG_CTRTWOFISH) -+ -+/* HASH type modifiers (A.2)*/ -+#define DRBG_HASHSHA1 ((u32)1<<4) -+#define DRBG_HASHSHA224 ((u32)1<<5) -+#define DRBG_HASHSHA256 ((u32)1<<6) -+#define DRBG_HASHSHA384 ((u32)1<<7) -+#define DRBG_HASHSHA512 ((u32)1<<8) -+#define DRBG_HASH_MASK (DRBG_HASHSHA1 | DRBG_HASHSHA224 \ -+ | DRBG_HASHSHA256 | DRBG_HASHSHA384 \ -+ | DRBG_HASHSHA512) -+/* type modifiers (A.3)*/ -+#define DRBG_HMAC ((u32)1<<12) -+#define DRBG_SYM128 ((u32)1<<13) -+#define DRBG_SYM192 ((u32)1<<14) -+#define DRBG_SYM256 ((u32)1<<15) -+#define DRBG_TYPE_MASK (DRBG_HMAC | DRBG_SYM128 | DRBG_SYM192 \ -+ | DRBG_SYM256) -+#define DRBG_CIPHER_MASK (DRBG_CTR_MASK | DRBG_HASH_MASK \ -+ | DRBG_TYPE_MASK) -+ -+#define DRBG_PR_CTRAES128 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM128) -+#define DRBG_PR_CTRAES192 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM192) -+#define DRBG_PR_CTRAES256 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM256) -+#define DRBG_NOPR_CTRAES128 (DRBG_CTRAES | DRBG_SYM128) -+#define DRBG_NOPR_CTRAES192 (DRBG_CTRAES | DRBG_SYM192) -+#define DRBG_NOPR_CTRAES256 (DRBG_CTRAES | DRBG_SYM256) -+#define DRBG_PR_HASHSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1) -+#define DRBG_PR_HASHSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256) -+#define DRBG_PR_HASHSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384) -+#define DRBG_PR_HASHSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512) -+#define DRBG_NOPR_HASHSHA1 (DRBG_HASHSHA1) -+#define DRBG_NOPR_HASHSHA256 (DRBG_HASHSHA256) -+#define DRBG_NOPR_HASHSHA384 (DRBG_HASHSHA384) -+#define DRBG_NOPR_HASHSHA512 (DRBG_HASHSHA512) -+#define DRBG_PR_HMACSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1 \ -+ | DRBG_HMAC) -+#define DRBG_PR_HMACSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256 \ -+ | DRBG_HMAC) -+#define DRBG_PR_HMACSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384 \ -+ | DRBG_HMAC) -+#define DRBG_PR_HMACSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512 \ -+ | DRBG_HMAC) -+#define DRBG_NOPR_HMACSHA1 (DRBG_HASHSHA1 | DRBG_HMAC) -+#define DRBG_NOPR_HMACSHA256 (DRBG_HASHSHA256 | DRBG_HMAC) -+#define DRBG_NOPR_HMACSHA384 (DRBG_HASHSHA384 | DRBG_HMAC) -+#define DRBG_NOPR_HMACSHA512 (DRBG_HASHSHA512 | DRBG_HMAC) -+ -+ -+/* The default DRGB type. */ -+#define DRBG_DEFAULT_TYPE DRBG_NOPR_HMACSHA256 -+ -+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -+ -+static char hex_char_map_l[] = { '0', '1', '2', '3', '4', '5', '6', '7', -+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; -+static char hex_char_map_u[] = { '0', '1', '2', '3', '4', '5', '6', '7', -+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; -+static char hex_char(unsigned int bin, int u) -+{ -+ if (bin < sizeof(hex_char_map_l)) -+ return (u) ? hex_char_map_u[bin] : hex_char_map_l[bin]; -+ return 'X'; -+} -+ -+/* -+ * Convert binary string into hex representation -+ * @bin input buffer with binary data -+ * @binlen length of bin -+ * @hex output buffer to store hex data -+ * @hexlen length of already allocated hex buffer (should be at least -+ * twice binlen -- if not, only a fraction of binlen is converted) -+ * @u case of hex characters (0=>lower case, 1=>upper case) -+ */ -+static void bin2hex(const unsigned char *bin, size_t binlen, -+ char *hex, size_t hexlen, int u) -+{ -+ size_t i = 0; -+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen; -+ -+ for (i = 0; i < chars; i++) { -+ hex[(i*2)] = hex_char((bin[i] >> 4), u); -+ hex[((i*2)+1)] = hex_char((bin[i] & 0x0f), u); -+ } -+} -+ -+static int bin_char(unsigned char hex) -+{ -+ if (48 <= hex && 57 >= hex) -+ return (hex - 48); -+ if (65 <= hex && 70 >= hex) -+ return (hex - 55); -+ if (97 <= hex && 102 >= hex) -+ return (hex - 87); -+ return 0; -+} -+/* -+ * Convert hex representation into binary string -+ * @hex input buffer with hex representation -+ * @hexlen length of hex -+ * @bin output buffer with binary data -+ * @binlen length of already allocated bin buffer (should be at least -+ * half of hexlen -- if not, only a fraction of hexlen is converted) -+ */ -+static void hex2bin(const unsigned char *hex, size_t hexlen, -+ unsigned char *bin, size_t binlen) -+{ -+ size_t i = 0; -+ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen; -+ -+ for (i = 0; i < chars; i++) { -+ bin[i] = bin_char(hex[(i*2)]) << 4; -+ bin[i] |= bin_char(hex[((i*2)+1)]); -+ } -+} -+ -+/* Print a error message and exit the process with an error code. */ -+static void -+die (const char *format, ...) -+{ -+ va_list arg_ptr; -+ -+ va_start (arg_ptr, format); -+ vfprintf (stderr, format, arg_ptr); -+ va_end (arg_ptr); -+ exit (1); -+} -+ -+ -+struct gcry_drbg_test_vector -+{ -+ u_int32_t flags; /* flags selecting the DRBG type */ -+ unsigned char *entropy; /* entropy string for initialization -- this -+ * string is a concatenation of the entropy -+ * and nonce variable from CAVS */ -+ size_t entropylen; /* length of entropy and nonce variable */ -+ unsigned char *entpra; /* for prediction resistance: entropy for -+ * first reseeding */ -+ unsigned char *entprb; /* for prediction resistance: entropy for -+ * second reseeding */ -+ size_t entprlen; /* length of prediction resistance entropy */ -+ unsigned char *addtla; /* additional input string for first random -+ * value */ -+ unsigned char *addtlb; /* additional input string for second random -+ * value */ -+ size_t addtllen; /* length of additional input string */ -+ unsigned char *pers; /* personalization string */ -+ size_t perslen; /* personalization string length */ -+ unsigned char *expected; /* expected random value -- for CAVS test, -+ this value does not apply and the memcmp -+ in drbg_cavs_test does not apply either*/ -+ size_t expectedlen; /* length of expected random value */ -+}; -+ -+struct gcry_drbg_test_vector drbg_test_pr[] = { -+ { -+ .flags = (DRBG_PR_HASHSHA256), -+ .entropy = (unsigned char *) -+ "\x72\x88\x4c\xcd\x6c\x85\x57\x70\xf7\x0b\x8b\x86" -+ "\xc1\xeb\xd2\x4e\x36\x14\xab\x18\xc4\x9c\xc9\xcf" -+ "\x1a\xe8\xf7\x7b\x02\x49\x73\xd7\xf1\x42\x7d\xc6" -+ "\x3f\x29\x2d\xec\xd3\x66\x51\x3f\x1d\x8d\x5b\x4e", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\x38\x9c\x91\xfa\xc2\xa3\x46\x89\x56\x08\x3f\x62" -+ "\x73\xd5\x22\xa9\x29\x63\x3a\x1d\xe5\x5d\x5e\x4f" -+ "\x67\xb0\x67\x7a\x5e\x9e\x0c\x62", -+ .entprb = (unsigned char *) -+ "\xb2\x8f\x36\xb2\xf6\x8d\x39\x13\xfa\x6c\x66\xcf" -+ "\x62\x8a\x7e\x8c\x12\x33\x71\x9c\x69\xe4\xa5\xf0" -+ "\x8c\xee\xeb\x9c\xf5\x31\x98\x31", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x52\x7b\xa3\xad\x71\x77\xa4\x49\x42\x04\x61\xc7" -+ "\xf0\xaf\xa5\xfd\xd3\xb3\x0d\x6a\x61\xba\x35\x49" -+ "\xbb\xaa\xaf\xe4\x25\x7d\xb5\x48\xaf\x5c\x18\x3d" -+ "\x33\x8d\x9d\x45\xdf\x98\xd5\x94\xa8\xda\x92\xfe" -+ "\xc4\x3c\x94\x2a\xcf\x7f\x7b\xf2\xeb\x28\xa9\xf1" -+ "\xe0\x86\x30\xa8\xfe\xf2\x48\x90\x91\x0c\x75\xb5" -+ "\x3c\x00\xf0\x4d\x09\x4f\x40\xa7\xa2\x8c\x52\xdf" -+ "\x52\xef\x17\xbf\x3d\xd1\xa2\x31\xb4\xb8\xdc\xe6" -+ "\x5b\x0d\x1f\x78\x36\xb4\xe6\x4b\xa7\x11\x25\xd5" -+ "\x94\xc6\x97\x36\xab\xf0\xe5\x31\x28\x6a\xbb\xce" -+ "\x30\x81\xa6\x8f\x27\x14\xf8\x1c", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = (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 = (DRBG_PR_HASHSHA256), -+ .entropy = (unsigned char *) -+ "\xc6\x1c\xaf\x83\xa2\x56\x38\xf9\xb0\xbc\xd9\x85" -+ "\xf5\x2e\xc4\x46\x9c\xe1\xb9\x40\x98\x70\x10\x72" -+ "\xd7\x7d\x15\x85\xa1\x83\x5a\x97\xdf\xc8\xa8\xe8" -+ "\x03\x4c\xcb\x70\x35\x8b\x90\x94\x46\x8a\x6e\xa1", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xc9\x05\xa4\xcf\x28\x80\x4b\x93\x0f\x8b\xc6\xf9" -+ "\x09\x41\x58\x74\xe9\xec\x28\xc7\x53\x0a\x73\x60" -+ "\xba\x0a\xde\x57\x5b\x4b\x9f\x29", -+ .entprb = (unsigned char *) -+ "\x4f\x31\xd2\xeb\xac\xfa\xa8\xe2\x01\x7d\xf3\xbd" -+ "\x42\xbd\x20\xa0\x30\x65\x74\xd5\x5d\xd2\xad\xa4" -+ "\xa9\xeb\x1f\x4d\xf6\xfd\xb8\x26", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\xf6\x13\x05\xcb\x83\x60\x16\x42\x49\x1d\xc6\x25" -+ "\x3b\x8c\x31\xa3\xbe\x8b\xbd\x1c\xe2\xec\x1d\xde" -+ "\xbb\xbf\xa1\xac\xa8\x9f\x50\xce\x69\xce\xef\xd5" -+ "\xd6\xf2\xef\x6a\xf7\x81\x38\xdf\xbc\xa7\x5a\xb9" -+ "\xb2\x42\x65\xab\xe4\x86\x8d\x2d\x9d\x59\x99\x2c" -+ "\x5a\x0d\x71\x55\x98\xa4\x45\xc2\x8d\xdb\x05\x5e" -+ "\x50\x21\xf7\xcd\xe8\x98\x43\xce\x57\x74\x63\x4c" -+ "\xf3\xb1\xa5\x14\x1e\x9e\x01\xeb\x54\xd9\x56\xae" -+ "\xbd\xb6\x6f\x1a\x47\x6b\x3b\x44\xe4\xa2\xe9\x3c" -+ "\x6c\x83\x12\x30\xb8\x78\x7f\x8e\x54\x82\xd4\xfe" -+ "\x90\x35\x0d\x4c\x4d\x85\xe7\x13", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\xa5\xbf\xac\x4f\x71\xa1\xbb\x67\x94\xc6\x50\xc7" -+ "\x2a\x45\x9e\x10\xa8\xed\xf7\x52\x4f\xfe\x21\x90" -+ "\xa4\x1b\xe1\xe2\x53\xcc\x61\x47", -+ .perslen = 32, -+ }, -+ { -+ .flags = (DRBG_PR_HASHSHA256), -+ .entropy = (unsigned char *) -+ "\xb6\xc1\x8d\xdf\x99\x54\xbe\x95\x10\x48\xd9\xf6" -+ "\xd7\x48\xa8\x73\x2d\x74\xde\x1e\xde\x57\x7e\xf4" -+ "\x7b\x7b\x64\xef\x88\x7a\xa8\x10\x4b\xe1\xc1\x87" -+ "\xbb\x0b\xe1\x39\x39\x50\xaf\x68\x9c\xa2\xbf\x5e", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xdc\x81\x0a\x01\x58\xa7\x2e\xce\xee\x48\x8c\x7c" -+ "\x77\x9e\x3c\xf1\x17\x24\x7a\xbb\xab\x9f\xca\x12" -+ "\x19\xaf\x97\x2d\x5f\xf9\xff\xfc", -+ .entprb = (unsigned char *) -+ "\xaf\xfc\x4f\x98\x8b\x93\x95\xc1\xb5\x8b\x7f\x73" -+ "\x6d\xa6\xbe\x6d\x33\xeb\x2c\x82\xb1\xaf\xc1\xb6" -+ "\xb6\x05\xe2\x44\xaa\xfd\xe7\xdb", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x51\x79\xde\x1c\x0f\x58\xf3\xf4\xc9\x57\x2e\x31" -+ "\xa7\x09\xa1\x53\x64\x63\xa2\xc5\x1d\x84\x88\x65" -+ "\x01\x1b\xc6\x16\x3c\x49\x5b\x42\x8e\x53\xf5\x18" -+ "\xad\x94\x12\x0d\x4f\x55\xcc\x45\x5c\x98\x0f\x42" -+ "\x28\x2f\x47\x11\xf9\xc4\x01\x97\x6b\xa0\x94\x50" -+ "\xa9\xd1\x5e\x06\x54\x3f\xdf\xbb\xc4\x98\xee\x8b" -+ "\xba\xa9\xfa\x49\xee\x1d\xdc\xfb\x50\xf6\x51\x9f" -+ "\x6c\x4a\x9a\x6f\x63\xa2\x7d\xad\xaf\x3a\x24\xa0" -+ "\xd9\x9f\x07\xeb\x15\xee\x26\xe0\xd5\x63\x39\xda" -+ "\x3c\x59\xd6\x33\x6c\x02\xe8\x05\x71\x46\x68\x44" -+ "\x63\x4a\x68\x72\xe9\xf5\x55\xfe", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\x15\x20\x2f\xf6\x98\x28\x63\xa2\xc4\x4e\xbb\x6c" -+ "\xb2\x25\x92\x61\x79\xc9\x22\xc4\x61\x54\x96\xff" -+ "\x4a\x85\xca\x80\xfe\x0d\x1c\xd0", -+ .addtlb = (unsigned char *) -+ "\xde\x29\x8e\x03\x42\x61\xa3\x28\x5e\xc8\x80\xc2" -+ "\x6d\xbf\xad\x13\xe1\x8d\x2a\xc7\xe8\xc7\x18\x89" -+ "\x42\x58\x9e\xd6\xcc\xad\x7b\x1e", -+ .addtllen = 32, -+ .pers = (unsigned char *) -+ "\x84\xc3\x73\x9e\xce\xb3\xbc\x89\xf7\x62\xb3\xe1" -+ "\xd7\x48\x45\x8a\xa9\xcc\xe9\xed\xd5\x81\x84\x52" -+ "\x82\x4c\xdc\x19\xb8\xf8\x92\x5c", -+ .perslen = 32, -+ }, -+ { -+ .flags = (DRBG_PR_HMACSHA256), -+ .entropy = (unsigned char *) -+ "\x99\x69\xe5\x4b\x47\x03\xff\x31\x78\x5b\x87\x9a" -+ "\x7e\x5c\x0e\xae\x0d\x3e\x30\x95\x59\xe9\xfe\x96" -+ "\xb0\x67\x6d\x49\xd5\x91\xea\x4d\x07\xd2\x0d\x46" -+ "\xd0\x64\x75\x7d\x30\x23\xca\xc2\x37\x61\x27\xab", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xc6\x0f\x29\x99\x10\x0f\x73\x8c\x10\xf7\x47\x92" -+ "\x67\x6a\x3f\xc4\xa2\x62\xd1\x37\x21\x79\x80\x46" -+ "\xe2\x9a\x29\x51\x81\x56\x9f\x54", -+ .entprb = (unsigned char *) -+ "\xc1\x1d\x45\x24\xc9\x07\x1b\xd3\x09\x60\x15\xfc" -+ "\xf7\xbc\x24\xa6\x07\xf2\x2f\xa0\x65\xc9\x37\x65" -+ "\x8a\x2a\x77\xa8\x69\x90\x89\xf4", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\xab\xc0\x15\x85\x60\x94\x80\x3a\x93\x8d\xff\xd2" -+ "\x0d\xa9\x48\x43\x87\x0e\xf9\x35\xb8\x2c\xfe\xc1" -+ "\x77\x06\xb8\xf5\x51\xb8\x38\x50\x44\x23\x5d\xd4" -+ "\x4b\x59\x9f\x94\xb3\x9b\xe7\x8d\xd4\x76\xe0\xcf" -+ "\x11\x30\x9c\x99\x5a\x73\x34\xe0\xa7\x8b\x37\xbc" -+ "\x95\x86\x23\x50\x86\xfa\x3b\x63\x7b\xa9\x1c\xf8" -+ "\xfb\x65\xef\xa2\x2a\x58\x9c\x13\x75\x31\xaa\x7b" -+ "\x2d\x4e\x26\x07\xaa\xc2\x72\x92\xb0\x1c\x69\x8e" -+ "\x6e\x01\xae\x67\x9e\xb8\x7c\x01\xa8\x9c\x74\x22" -+ "\xd4\x37\x2d\x6d\x75\x4a\xba\xbb\x4b\xf8\x96\xfc" -+ "\xb1\xcd\x09\xd6\x92\xd0\x28\x3f", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = (DRBG_PR_HMACSHA256), -+ .entropy = (unsigned char *) -+ "\xb9\x1f\xe9\xef\xdd\x9b\x7d\x20\xb6\xec\xe0\x2f" -+ "\xdb\x76\x24\xce\x41\xc8\x3a\x4a\x12\x7f\x3e\x2f" -+ "\xae\x05\x99\xea\xb5\x06\x71\x0d\x0c\x4c\xb4\x05" -+ "\x26\xc6\xbd\xf5\x7f\x2a\x3d\xf2\xb5\x49\x7b\xda", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xef\x67\x50\x9c\xa7\x7d\xdf\xb7\x2d\x81\x01\xa4" -+ "\x62\x81\x6a\x69\x5b\xb3\x37\x45\xa7\x34\x8e\x26" -+ "\x46\xd9\x26\xa2\x19\xd4\x94\x43", -+ .entprb = (unsigned char *) -+ "\x97\x75\x53\x53\xba\xb4\xa6\xb2\x91\x60\x71\x79" -+ "\xd1\x6b\x4a\x24\x9a\x34\x66\xcc\x33\xab\x07\x98" -+ "\x51\x78\x72\xb2\x79\xfd\x2c\xff", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x9c\xdc\x63\x8a\x19\x23\x22\x66\x0c\xc5\xb9\xd7" -+ "\xfb\x2a\xb0\x31\xe3\x8a\x36\xa8\x5a\xa8\x14\xda" -+ "\x1e\xa9\xcc\xfe\xb8\x26\x44\x83\x9f\xf6\xff\xaa" -+ "\xc8\x98\xb8\x30\x35\x3b\x3d\x36\xd2\x49\xd4\x40" -+ "\x62\x0a\x65\x10\x76\x55\xef\xc0\x95\x9c\xa7\xda" -+ "\x3f\xcf\xb7\x7b\xc6\xe1\x28\x52\xfc\x0c\xe2\x37" -+ "\x0d\x83\xa7\x51\x4b\x31\x47\x3c\xe1\x3c\xae\x70" -+ "\x01\xc8\xa3\xd3\xc2\xac\x77\x9c\xd1\x68\x77\x9b" -+ "\x58\x27\x3b\xa5\x0f\xc2\x7a\x8b\x04\x65\x62\xd5" -+ "\xe8\xd6\xfe\x2a\xaf\xd3\xd3\xfe\xbd\x18\xfb\xcd" -+ "\xcd\x66\xb5\x01\x69\x66\xa0\x3c", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\x17\xc1\x56\xcb\xcc\x50\xd6\x03\x7d\x45\x76\xa3" -+ "\x75\x76\xc1\x4a\x66\x1b\x2e\xdf\xb0\x2e\x7d\x56" -+ "\x6d\x99\x3b\xc6\x58\xda\x03\xf6", -+ .addtlb = (unsigned char *) -+ "\x7c\x7b\x4a\x4b\x32\x5e\x6f\x67\x34\xf5\x21\x4c" -+ "\xf9\x96\xf9\xbf\x1c\x8c\x81\xd3\x9b\x60\x6a\x44" -+ "\xc6\x03\xa2\xfb\x13\x20\x19\xb7", -+ .addtllen = 32, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = (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 = (DRBG_PR_HMACSHA256), -+ .entropy = (unsigned char *) -+ "\xc7\xcc\xbc\x67\x7e\x21\x66\x1e\x27\x2b\x63\xdd" -+ "\x3a\x78\xdc\xdf\x66\x6d\x3f\x24\xae\xcf\x37\x01" -+ "\xa9\x0d\x89\x8a\xa7\xdc\x81\x58\xae\xb2\x10\x15" -+ "\x7e\x18\x44\x6d\x13\xea\xdf\x37\x85\xfe\x81\xfb", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\x7b\xa1\x91\x5b\x3c\x04\xc4\x1b\x1d\x19\x2f\x1a" -+ "\x18\x81\x60\x3c\x6c\x62\x91\xb7\xe9\xf5\xcb\x96" -+ "\xbb\x81\x6a\xcc\xb5\xae\x55\xb6", -+ .entprb = (unsigned char *) -+ "\x99\x2c\xc7\x78\x7e\x3b\x88\x12\xef\xbe\xd3\xd2" -+ "\x7d\x2a\xa5\x86\xda\x8d\x58\x73\x4a\x0a\xb2\x2e" -+ "\xbb\x4c\x7e\xe3\x9a\xb6\x81\xc1", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x95\x6f\x95\xfc\x3b\xb7\xfe\x3e\xd0\x4e\x1a\x14" -+ "\x6c\x34\x7f\x7b\x1d\x0d\x63\x5e\x48\x9c\x69\xe6" -+ "\x46\x07\xd2\x87\xf3\x86\x52\x3d\x98\x27\x5e\xd7" -+ "\x54\xe7\x75\x50\x4f\xfb\x4d\xfd\xac\x2f\x4b\x77" -+ "\xcf\x9e\x8e\xcc\x16\xa2\x24\xcd\x53\xde\x3e\xc5" -+ "\x55\x5d\xd5\x26\x3f\x89\xdf\xca\x8b\x4e\x1e\xb6" -+ "\x88\x78\x63\x5c\xa2\x63\x98\x4e\x6f\x25\x59\xb1" -+ "\x5f\x2b\x23\xb0\x4b\xa5\x18\x5d\xc2\x15\x74\x40" -+ "\x59\x4c\xb4\x1e\xcf\x9a\x36\xfd\x43\xe2\x03\xb8" -+ "\x59\x91\x30\x89\x2a\xc8\x5a\x43\x23\x7c\x73\x72" -+ "\xda\x3f\xad\x2b\xba\x00\x6b\xd1", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\x18\xe8\x17\xff\xef\x39\xc7\x41\x5c\x73\x03\x03" -+ "\xf6\x3d\xe8\x5f\xc8\xab\xe4\xab\x0f\xad\xe8\xd6" -+ "\x86\x88\x55\x28\xc1\x69\xdd\x76", -+ .addtlb = (unsigned char *) -+ "\xac\x07\xfc\xbe\x87\x0e\xd3\xea\x1f\x7e\xb8\xe7" -+ "\x9d\xec\xe8\xe7\xbc\xf3\x18\x25\x77\x35\x4a\xaa" -+ "\x00\x99\x2a\xdd\x0a\x00\x50\x82", -+ .addtllen = 32, -+ .pers = (unsigned char *) -+ "\xbc\x55\xab\x3c\xf6\x52\xb0\x11\x3d\x7b\x90\xb8" -+ "\x24\xc9\x26\x4e\x5a\x1e\x77\x0d\x3d\x58\x4a\xda" -+ "\xd1\x81\xe9\xf8\xeb\x30\x8f\x6f", -+ .perslen = 32, -+ }, -+ { -+ .flags = (DRBG_PR_CTRAES128), -+ .entropy = (unsigned char *) -+ "\xd1\x44\xc6\x61\x81\x6d\xca\x9d\x15\x28\x8a\x42" -+ "\x94\xd7\x28\x9c\x43\x77\x19\x29\x1a\x6d\xc3\xa2", -+ .entropylen = 24, -+ .entpra = (unsigned char *) -+ "\x96\xd8\x9e\x45\x32\xc9\xd2\x08\x7a\x6d\x97\x15" "\xb4\xec\x80\xb1", -+ .entprb = (unsigned char *) -+ "\x8b\xb6\x72\xb5\x24\x0b\x98\x65\x95\x95\xe9\xc9" "\x28\x07\xeb\xc2", -+ .entprlen = 16, -+ .expected = (unsigned char *) -+ "\x70\x19\xd0\x4c\x45\x78\xd6\x68\xa9\x9a\xaa\xfe" -+ "\xc1\xdf\x27\x9a\x1c\x0d\x0d\xf7\x24\x75\x46\xcc" -+ "\x77\x6b\xdf\x89\xc6\x94\xdc\x74\x50\x10\x70\x18" -+ "\x9b\xdc\x96\xb4\x89\x23\x40\x1a\xce\x09\x87\xce" -+ "\xd2\xf3\xd5\xe4\x51\x67\x74\x11\x5a\xcc\x8b\x3b" "\x8a\xf1\x23\xa8", -+ .expectedlen = 64, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = (DRBG_PR_CTRAES128), -+ .entropy = (unsigned char *) -+ "\x8e\x83\xe0\xeb\x37\xea\x3e\x53\x5e\x17\x6e\x77" -+ "\xbd\xb1\x53\x90\xfc\xdc\xc1\x3c\x9a\x88\x22\x94", -+ .entropylen = 24, -+ .entpra = (unsigned char *) -+ "\x6a\x85\xe7\x37\xc8\xf1\x04\x31\x98\x4f\xc8\x73" "\x67\xd1\x08\xf8", -+ .entprb = (unsigned char *) -+ "\xd7\xa4\x68\xe2\x12\x74\xc3\xd9\xf1\xb7\x05\xbc" "\xd4\xba\x04\x58", -+ .entprlen = 16, -+ .expected = (unsigned char *) -+ "\x78\xd6\xa6\x70\xff\xd1\x82\xf5\xa2\x88\x7f\x6d" -+ "\x3d\x8c\x39\xb1\xa8\xcb\x2c\x91\xab\x14\x7e\xbc" -+ "\x95\x45\x9f\x24\xb8\x20\xac\x21\x23\xdb\x72\xd7" -+ "\x12\x8d\x48\x95\xf3\x19\x0c\x43\xc6\x19\x45\xfc" -+ "\x8b\xac\x40\x29\x73\x00\x03\x45\x5e\x12\xff\x0c" "\xc1\x02\x41\x82", -+ .expectedlen = 64, -+ .addtla = (unsigned char *) -+ "\xa2\xd9\x38\xcf\x8b\x29\x67\x5b\x65\x62\x6f\xe8" "\xeb\xb3\x01\x76", -+ .addtlb = (unsigned char *) -+ "\x59\x63\x1e\x81\x8a\x14\xa8\xbb\xa1\xb8\x41\x25" "\xd0\x7f\xcc\x43", -+ .addtllen = 16, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = (DRBG_PR_CTRAES128), -+ .entropy = (unsigned char *) -+ "\x04\xd9\x49\xa6\xdc\xe8\x6e\xbb\xf1\x08\x77\x2b" -+ "\x9e\x08\xca\x92\x65\x16\xda\x99\xa2\x59\xf3\xe8", -+ .entropylen = 24, -+ .entpra = (unsigned char *) -+ "\x38\x7e\x3f\x6b\x51\x70\x7b\x20\xec\x53\xd0\x66" "\xc3\x0f\xe3\xb0", -+ .entprb = (unsigned char *) -+ "\xe0\x86\xa6\xaa\x5f\x72\x2f\xad\xf7\xef\x06\xb8" "\xd6\x9c\x9d\xe8", -+ .entprlen = 16, -+ .expected = (unsigned char *) -+ "\xc9\x0a\xaf\x85\x89\x71\x44\x66\x4f\x25\x0b\x2b" -+ "\xde\xd8\xfa\xff\x52\x5a\x1b\x32\x5e\x41\x7a\x10" -+ "\x1f\xef\x1e\x62\x23\xe9\x20\x30\xc9\x0d\xad\x69" -+ "\xb4\x9c\x5b\xf4\x87\x42\xd5\xae\x5e\x5e\x43\xcc" -+ "\xd9\xfd\x0b\x93\x4a\xe3\xd4\x06\x37\x36\x0f\x3f" "\x72\x82\x0c\xcf", -+ .expectedlen = 64, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\xbf\xa4\x9a\x8f\x7b\xd8\xb1\x7a\x9d\xfa\x45\xed" "\x21\x52\xb3\xad", -+ .perslen = 16, -+ }, -+ { -+ .flags = (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 drbg_test_nopr[] = { -+ { -+ .flags = DRBG_NOPR_HASHSHA256, -+ .entropy = (unsigned char *) -+ "\xa6\x5a\xd0\xf3\x45\xdb\x4e\x0e\xff\xe8\x75\xc3" -+ "\xa2\xe7\x1f\x42\xc7\x12\x9d\x62\x0f\xf5\xc1\x19" -+ "\xa9\xef\x55\xf0\x51\x85\xe0\xfb\x85\x81\xf9\x31" -+ "\x75\x17\x27\x6e\x06\xe9\x60\x7d\xdb\xcb\xcc\x2e", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\xd3\xe1\x60\xc3\x5b\x99\xf3\x40\xb2\x62\x82\x64" -+ "\xd1\x75\x10\x60\xe0\x04\x5d\xa3\x83\xff\x57\xa5" -+ "\x7d\x73\xa6\x73\xd2\xb8\xd8\x0d\xaa\xf6\xa6\xc3" -+ "\x5a\x91\xbb\x45\x79\xd7\x3f\xd0\xc8\xfe\xd1\x11" -+ "\xb0\x39\x13\x06\x82\x8a\xdf\xed\x52\x8f\x01\x81" -+ "\x21\xb3\xfe\xbd\xc3\x43\xe7\x97\xb8\x7d\xbb\x63" -+ "\xdb\x13\x33\xde\xd9\xd1\xec\xe1\x77\xcf\xa6\xb7" -+ "\x1f\xe8\xab\x1d\xa4\x66\x24\xed\x64\x15\xe5\x1c" -+ "\xcd\xe2\xc7\xca\x86\xe2\x83\x99\x0e\xea\xeb\x91" -+ "\x12\x04\x15\x52\x8b\x22\x95\x91\x02\x81\xb0\x2d" -+ "\xd4\x31\xf4\xc9\xf7\x04\x27\xdf", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = 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 = DRBG_NOPR_HASHSHA256, -+ .entropy = (unsigned char *) -+ "\x2a\x85\xa9\x8b\xd0\xda\x83\xd6\xad\xab\x9f\xbb" -+ "\x54\x31\x15\x95\x1c\x4d\x49\x9f\x6a\x15\xf6\xe4" -+ "\x15\x50\x88\x06\x29\x0d\xed\x8d\xb9\x6f\x96\xe1" -+ "\x83\x9f\xf7\x88\xda\x84\xbf\x44\x28\xd9\x1d\xaa", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\x2d\x55\xde\xc9\xed\x05\x47\x07\x3d\x04\xfc\x28" -+ "\x0f\x92\xf0\x4d\xd8\x00\x32\x47\x0a\x1b\x1c\x4b" -+ "\xef\xd9\x97\xa1\x17\x67\xda\x26\x6c\xfe\x76\x46" -+ "\x6f\xbc\x6d\x82\x4e\x83\x8a\x98\x66\x6c\x01\xb6" -+ "\xe6\x64\xe0\x08\x10\x6f\xd3\x5d\x90\xe7\x0d\x72" -+ "\xa6\xa7\xe3\xbb\x98\x11\x12\x56\x23\xc2\x6d\xd1" -+ "\xc8\xa8\x7a\x39\xf3\x34\xe3\xb8\xf8\x66\x00\x77" -+ "\x7d\xcf\x3c\x3e\xfa\xc9\x0f\xaf\xe0\x24\xfa\xe9" -+ "\x84\xf9\x6a\x01\xf6\x35\xdb\x5c\xab\x2a\xef\x4e" -+ "\xac\xab\x55\xb8\x9b\xef\x98\x68\xaf\x51\xd8\x16" -+ "\xa5\x5e\xae\xf9\x1e\xd2\xdb\xe6", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\xa8\x80\xec\x98\x30\x98\x15\xd2\xc6\xc4\x68\xf1" -+ "\x3a\x1c\xbf\xce\x6a\x40\x14\xeb\x36\x99\x53\xda" -+ "\x57\x6b\xce\xa4\x1c\x66\x3d\xbc", -+ .perslen = 32, -+ }, -+ { -+ .flags = DRBG_NOPR_HASHSHA256, -+ .entropy = (unsigned char *) -+ "\x69\xed\x82\xa9\xc5\x7b\xbf\xe5\x1d\x2f\xcb\x7a" -+ "\xd3\x50\x7d\x96\xb4\xb9\x2b\x50\x77\x51\x27\x74" -+ "\x33\x74\xba\xf1\x30\xdf\x8e\xdf\x87\x1d\x87\xbc" -+ "\x96\xb2\xc3\xa7\xed\x60\x5e\x61\x4e\x51\x29\x1a", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\xa5\x71\x24\x31\x11\xfe\x13\xe1\xa8\x24\x12\xfb" -+ "\x37\xa1\x27\xa5\xab\x77\xa1\x9f\xae\x8f\xaf\x13" -+ "\x93\xf7\x53\x85\x91\xb6\x1b\xab\xd4\x6b\xea\xb6" -+ "\xef\xda\x4c\x90\x6e\xef\x5f\xde\xe1\xc7\x10\x36" -+ "\xd5\x67\xbd\x14\xb6\x89\x21\x0c\xc9\x92\x65\x64" -+ "\xd0\xf3\x23\xe0\x7f\xd1\xe8\x75\xc2\x85\x06\xea" -+ "\xca\xc0\xcb\x79\x2d\x29\x82\xfc\xaa\x9a\xc6\x95" -+ "\x7e\xdc\x88\x65\xba\xec\x0e\x16\x87\xec\xa3\x9e" -+ "\xd8\x8c\x80\xab\x3a\x64\xe0\xcb\x0e\x45\x98\xdd" -+ "\x7c\x6c\x6c\x26\x11\x13\xc8\xce\xa9\x47\xa6\x06" -+ "\x57\xa2\x66\xbb\x2d\x7f\xf3\xc1", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\x74\xd3\x6d\xda\xe8\xd6\x86\x5f\x63\x01\xfd\xf2" -+ "\x7d\x06\x29\x6d\x94\xd1\x66\xf0\xd2\x72\x67\x4e" -+ "\x77\xc5\x3d\x9e\x03\xe3\xa5\x78", -+ .addtlb = (unsigned char *) -+ "\xf6\xb6\x3d\xf0\x7c\x26\x04\xc5\x8b\xcd\x3e\x6a" -+ "\x9f\x9c\x3a\x2e\xdb\x47\x87\xe5\x8e\x00\x5e\x2b" -+ "\x74\x7f\xa6\xf6\x80\xcd\x9b\x21", -+ .addtllen = 32, -+ .pers = (unsigned char *) -+ "\x74\xa6\xe0\x08\xf9\x27\xee\x1d\x6e\x3c\x28\x20" -+ "\x87\xdd\xd7\x54\x31\x47\x78\x4b\xe5\x6d\xa3\x73" -+ "\xa9\x65\xb1\x10\xc1\xdc\x77\x7c", -+ .perslen = 32, -+ }, -+ { -+ .flags = DRBG_NOPR_HMACSHA256, -+ .entropy = (unsigned char *) -+ "\xca\x85\x19\x11\x34\x93\x84\xbf\xfe\x89\xde\x1c" -+ "\xbd\xc4\x6e\x68\x31\xe4\x4d\x34\xa4\xfb\x93\x5e" -+ "\xe2\x85\xdd\x14\xb7\x1a\x74\x88\x65\x9b\xa9\x6c" -+ "\x60\x1d\xc6\x9f\xc9\x02\x94\x08\x05\xec\x0c\xa8", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\xe5\x28\xe9\xab\xf2\xde\xce\x54\xd4\x7c\x7e\x75" -+ "\xe5\xfe\x30\x21\x49\xf8\x17\xea\x9f\xb4\xbe\xe6" -+ "\xf4\x19\x96\x97\xd0\x4d\x5b\x89\xd5\x4f\xbb\x97" -+ "\x8a\x15\xb5\xc4\x43\xc9\xec\x21\x03\x6d\x24\x60" -+ "\xb6\xf7\x3e\xba\xd0\xdc\x2a\xba\x6e\x62\x4a\xbf" -+ "\x07\x74\x5b\xc1\x07\x69\x4b\xb7\x54\x7b\xb0\x99" -+ "\x5f\x70\xde\x25\xd6\xb2\x9e\x2d\x30\x11\xbb\x19" -+ "\xd2\x76\x76\xc0\x71\x62\xc8\xb5\xcc\xde\x06\x68" -+ "\x96\x1d\xf8\x68\x03\x48\x2c\xb3\x7e\xd6\xd5\xc0" -+ "\xbb\x8d\x50\xcf\x1f\x50\xd4\x76\xaa\x04\x58\xbd" -+ "\xab\xa8\x06\xf4\x8b\xe9\xdc\xb8", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = DRBG_NOPR_HMACSHA256, -+ .entropy = (unsigned char *) -+ "\xf9\x7a\x3c\xfd\x91\xfa\xa0\x46\xb9\xe6\x1b\x94" -+ "\x93\xd4\x36\xc4\x93\x1f\x60\x4b\x22\xf1\x08\x15" -+ "\x21\xb3\x41\x91\x51\xe8\xff\x06\x11\xf3\xa7\xd4" -+ "\x35\x95\x35\x7d\x58\x12\x0b\xd1\xe2\xdd\x8a\xed", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\xc6\x87\x1c\xff\x08\x24\xfe\x55\xea\x76\x89\xa5" -+ "\x22\x29\x88\x67\x30\x45\x0e\x5d\x36\x2d\xa5\xbf" -+ "\x59\x0d\xcf\x9a\xcd\x67\xfe\xd4\xcb\x32\x10\x7d" -+ "\xf5\xd0\x39\x69\xa6\x6b\x1f\x64\x94\xfd\xf5\xd6" -+ "\x3d\x5b\x4d\x0d\x34\xea\x73\x99\xa0\x7d\x01\x16" -+ "\x12\x6d\x0d\x51\x8c\x7c\x55\xba\x46\xe1\x2f\x62" -+ "\xef\xc8\xfe\x28\xa5\x1c\x9d\x42\x8e\x6d\x37\x1d" -+ "\x73\x97\xab\x31\x9f\xc7\x3d\xed\x47\x22\xe5\xb4" -+ "\xf3\x00\x04\x03\x2a\x61\x28\xdf\x5e\x74\x97\xec" -+ "\xf8\x2c\xa7\xb0\xa5\x0e\x86\x7e\xf6\x72\x8a\x4f" -+ "\x50\x9a\x8c\x85\x90\x87\x03\x9c", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\x51\x72\x89\xaf\xe4\x44\xa0\xfe\x5e\xd1\xa4\x1d" -+ "\xbb\xb5\xeb\x17\x15\x00\x79\xbd\xd3\x1e\x29\xcf" -+ "\x2f\xf3\x00\x34\xd8\x26\x8e\x3b", -+ .addtlb = (unsigned char *) -+ "\x88\x02\x8d\x29\xef\x80\xb4\xe6\xf0\xfe\x12\xf9" -+ "\x1d\x74\x49\xfe\x75\x06\x26\x82\xe8\x9c\x57\x14" -+ "\x40\xc0\xc9\xb5\x2c\x42\xa6\xe0", -+ .addtllen = 32, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = 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 = DRBG_NOPR_HMACSHA256, -+ .entropy = (unsigned char *) -+ "\xc2\xa5\x66\xa9\xa1\x81\x7b\x15\xc5\xc3\xb7\x78" -+ "\x17\x7a\xc8\x7c\x24\xe7\x97\xbe\x0a\x84\x5f\x11" -+ "\xc2\xfe\x39\x9d\xd3\x77\x32\xf2\xcb\x18\x94\xeb" -+ "\x2b\x97\xb3\xc5\x6e\x62\x83\x29\x51\x6f\x86\xec", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\xb3\xa3\x69\x8d\x77\x76\x99\xa0\xdd\x9f\xa3\xf0" -+ "\xa9\xfa\x57\x83\x2d\x3c\xef\xac\x5d\xf2\x44\x37" -+ "\xc6\xd7\x3a\x0f\xe4\x10\x40\xf1\x72\x90\x38\xae" -+ "\xf1\xe9\x26\x35\x2e\xa5\x9d\xe1\x20\xbf\xb7\xb0" -+ "\x73\x18\x3a\x34\x10\x6e\xfe\xd6\x27\x8f\xf8\xad" -+ "\x84\x4b\xa0\x44\x81\x15\xdf\xdd\xf3\x31\x9a\x82" -+ "\xde\x6b\xb1\x1d\x80\xbd\x87\x1a\x9a\xcd\x35\xc7" -+ "\x36\x45\xe1\x27\x0f\xb9\xfe\x4f\xa8\x8e\xc0\xe4" -+ "\x65\x40\x9e\xa0\xcb\xa8\x09\xfe\x2f\x45\xe0\x49" -+ "\x43\xa2\xe3\x96\xbb\xb7\xdd\x2f\x4e\x07\x95\x30" -+ "\x35\x24\xcc\x9c\xc5\xea\x54\xa1", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\x41\x3d\xd8\x3f\xe5\x68\x35\xab\xd4\x78\xcb\x96" -+ "\x93\xd6\x76\x35\x90\x1c\x40\x23\x9a\x26\x64\x62" -+ "\xd3\x13\x3b\x83\xe4\x9c\x82\x0b", -+ .addtlb = (unsigned char *) -+ "\xd5\xc4\xa7\x1f\x9d\x6d\x95\xa1\xbe\xdf\x0b\xd2" -+ "\x24\x7c\x27\x7d\x1f\x84\xa4\xe5\x7a\x4a\x88\x25" -+ "\xb8\x2a\x2d\x09\x7d\xe6\x3e\xf1", -+ .addtllen = 32, -+ .pers = (unsigned char *) -+ "\x13\xce\x4d\x8d\xd2\xdb\x97\x96\xf9\x41\x56\xc8" -+ "\xe8\xf0\x76\x9b\x0a\xa1\xc8\x2c\x13\x23\xb6\x15" -+ "\x36\x60\x3b\xca\x37\xc9\xee\x29", -+ .perslen = 32, -+ }, -+ { -+ .flags = DRBG_NOPR_CTRAES192, -+ .entropy = (unsigned char *) -+ "\xc3\x5c\x2f\xa2\xa8\x9d\x52\xa1\x1f\xa3\x2a\xa9" -+ "\x6c\x95\xb8\xf1\xc9\xa8\xf9\xcb\x24\x5a\x8b\x40" -+ "\xf3\xa6\xe5\xa7\xfb\xd9\xd3\xc6\x8e\x27\x7b\xa9" "\xac\x9b\xbb\x00", -+ .entropylen = 40, -+ .expected = (unsigned char *) -+ "\x8c\x2e\x72\xab\xfd\x9b\xb8\x28\x4d\xb7\x9e\x17" -+ "\xa4\x3a\x31\x46\xcd\x76\x94\xe3\x52\x49\xfc\x33" -+ "\x83\x91\x4a\x71\x17\xf4\x13\x68\xe6\xd4\xf1\x48" -+ "\xff\x49\xbf\x29\x07\x6b\x50\x15\xc5\x9f\x45\x79" -+ "\x45\x66\x2e\x3d\x35\x03\x84\x3f\x4a\xa5\xa3\xdf" "\x9a\x9d\xf1\x0d", -+ .expectedlen = 64, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = DRBG_NOPR_CTRAES256, -+ .entropy = (unsigned char *) -+ "\x36\x40\x19\x40\xfa\x8b\x1f\xba\x91\xa1\x66\x1f" -+ "\x21\x1d\x78\xa0\xb9\x38\x9a\x74\xe5\xbc\xcf\xec" -+ "\xe8\xd7\x66\xaf\x1a\x6d\x3b\x14\x49\x6f\x25\xb0" -+ "\xf1\x30\x1b\x4f\x50\x1b\xe3\x03\x80\xa1\x37\xeb", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\x58\x62\xeb\x38\xbd\x55\x8d\xd9\x78\xa6\x96\xe6" -+ "\xdf\x16\x47\x82\xdd\xd8\x87\xe7\xe9\xa6\xc9\xf3" -+ "\xf1\xfb\xaf\xb7\x89\x41\xb5\x35\xa6\x49\x12\xdf" -+ "\xd2\x24\xc6\xdc\x74\x54\xe5\x25\x0b\x3d\x97\x16" -+ "\x5e\x16\x26\x0c\x2f\xaf\x1c\xc7\x73\x5c\xb7\x5f" "\xb4\xf0\x7e\x1d", -+ .expectedlen = 64, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = DRBG_NOPR_CTRAES128, -+ .entropy = (unsigned char *) -+ "\x87\xe1\xc5\x32\x99\x7f\x57\xa3\x5c\x28\x6d\xe8" -+ "\x64\xbf\xf2\x64\xa3\x9e\x98\xdb\x6c\x10\x78\x7f", -+ .entropylen = 24, -+ .expected = (unsigned char *) -+ "\x2c\x14\x7e\x24\x11\x9a\xd8\xd4\xb2\xed\x61\xc1" -+ "\x53\xd0\x50\xc9\x24\xff\x59\x75\x15\xf1\x17\x3a" -+ "\x3d\xf4\x4b\x2c\x84\x28\xef\x89\x0e\xb9\xde\xf3" -+ "\xe4\x78\x04\xb2\xfd\x9b\x35\x7f\xe1\x3f\x8a\x3e" -+ "\x10\xc8\x67\x0a\xf9\xdf\x2d\x6c\x96\xfb\xb2\xb8" "\xcb\x2d\xd6\xb0", -+ .expectedlen = 64, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = DRBG_NOPR_CTRAES128, -+ .entropy = (unsigned char *) -+ "\x71\xbd\xce\x35\x42\x7d\x20\xbf\x58\xcf\x17\x74" -+ "\xce\x72\xd8\x33\x34\x50\x2d\x8f\x5b\x14\xc4\xdd", -+ .entropylen = 24, -+ .expected = (unsigned char *) -+ "\x97\x33\xe8\x20\x12\xe2\x7b\xa1\x46\x8f\xf2\x34" -+ "\xb3\xc9\xb6\x6b\x20\xb2\x4f\xee\x27\xd8\x0b\x21" -+ "\x8c\xff\x63\x73\x69\x29\xfb\xf3\x85\xcd\x88\x8e" -+ "\x43\x2c\x71\x8b\xa2\x55\xd2\x0f\x1d\x7f\xe3\xe1" -+ "\x2a\xa3\xe9\x2c\x25\x89\xc7\x14\x52\x99\x56\xcc" "\xc3\xdf\xb3\x81", -+ .expectedlen = 64, -+ .addtla = (unsigned char *) -+ "\x66\xef\x42\xd6\x9a\x8c\x3d\x6d\x4a\x9e\x95\xa6" "\x91\x4d\x81\x56", -+ .addtlb = (unsigned char *) -+ "\xe3\x18\x83\xd9\x4b\x5e\xc4\xcc\xaa\x61\x2f\xbb" "\x4a\x55\xd1\xc6", -+ .addtllen = 16, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = DRBG_NOPR_CTRAES128, -+ .entropy = (unsigned char *) -+ "\xca\x4b\x1e\xfa\x75\xbd\x69\x36\x38\x73\xb8\xf9" -+ "\xdb\x4d\x35\x0e\x47\xbf\x6c\x37\x72\xfd\xf7\xa9", -+ .entropylen = 24, -+ .expected = (unsigned char *) -+ "\x59\xc3\x19\x79\x1b\xb1\xf3\x0e\xe9\x34\xae\x6e" -+ "\x8b\x1f\xad\x1f\x74\xca\x25\x45\x68\xb8\x7f\x75" -+ "\x12\xf8\xf2\xab\x4c\x23\x01\x03\x05\xe1\x70\xee" -+ "\x75\xd8\xcb\xeb\x23\x4c\x7a\x23\x6e\x12\x27\xdb" -+ "\x6f\x7a\xac\x3c\x44\xb7\x87\x4b\x65\x56\x74\x45" "\x34\x30\x0c\x3d", -+ .expectedlen = 64, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\xeb\xaa\x60\x2c\x4d\xbe\x33\xff\x1b\xef\xbf\x0a" "\x0b\xc6\x97\x54", -+ .perslen = 16, -+ }, -+ { -+ .flags = 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, -+ }, -+}; -+ -+struct drbg_flags -+{ -+ u_int32_t flags; -+}; -+ -+gpg_err_code_t -+gcry_drbg_cavs_test (struct gcry_drbg_test_vector *test, unsigned char *buf); -+extern gpg_err_code_t -+gcry_drbg_healthcheck_one (struct gcry_drbg_test_vector *test); -+ -+void builtin_test(void) -+{ -+ /* this must be larger than 128 as otherwise there is a crash */ -+#define OUTLEN 150 -+ char rndbuf[OUTLEN]; -+ char out[(OUTLEN * 2 + 1)]; -+ int i = 0; -+ int ret = 0; -+ int result = 0; -+ struct drbg_flags tests[] = -+ { -+ { .flags = DRBG_PR_HMACSHA1 }, -+ { .flags = DRBG_PR_HMACSHA256 }, -+ { .flags = DRBG_PR_HMACSHA384 }, -+ { .flags = DRBG_PR_HMACSHA512 }, -+ { .flags = DRBG_NOPR_HMACSHA1 }, -+ { .flags = DRBG_NOPR_HMACSHA256 }, -+ { .flags = DRBG_NOPR_HMACSHA384 }, -+ { .flags = DRBG_NOPR_HMACSHA512 }, -+ { .flags = DRBG_PR_HASHSHA1 }, -+ { .flags = DRBG_PR_HASHSHA256 }, -+ { .flags = DRBG_PR_HASHSHA384 }, -+ { .flags = DRBG_PR_HASHSHA512 }, -+ { .flags = DRBG_NOPR_HASHSHA1 }, -+ { .flags = DRBG_NOPR_HASHSHA256 }, -+ { .flags = DRBG_NOPR_HASHSHA384 }, -+ { .flags = DRBG_NOPR_HASHSHA512 }, -+ { .flags = DRBG_PR_CTRAES128 }, -+ { .flags = DRBG_PR_CTRAES192 }, -+ { .flags = DRBG_PR_CTRAES256 }, -+ { .flags = DRBG_NOPR_CTRAES128 }, -+ { .flags = DRBG_NOPR_CTRAES192 }, -+ { .flags = DRBG_NOPR_CTRAES256 }, -+ }; -+ -+ for(i = 0; ARRAY_SIZE(tests) > i; i++) -+ { -+ ret = gcry_control(GCRYCTL_DRBG_REINIT, tests[i].flags, NULL, 0); -+ if(0 == ret) -+ { -+ printf("Test PASS: enabling DRBG %d\n", i); -+ memset(rndbuf, 0, OUTLEN); -+ gcry_randomize(&rndbuf, OUTLEN, GCRY_STRONG_RANDOM); -+ memset(out, 0, sizeof(out)); -+ bin2hex(rndbuf, OUTLEN, out, sizeof(out), 0); -+ printf("Test PASS: gcry_randomize generated strong random bytes for DRBG %d: %s\n", i, out); -+ } -+ else -+ { -+ printf("Test FAIL: enabling DRBG %d\n", i); -+ result += ret; -+ } -+ } -+ -+ ret = gcry_control(GCRYCTL_DRBG_REINIT, 29, NULL, NULL); -+ if(0 == ret) -+ printf("Test FAIL: enabling unknown DRBG\n"); -+ else -+ printf("Test PASS: not enabling unknown DRBG\n"); -+ -+ for(i = 0; ARRAY_SIZE(drbg_test_nopr) > i; i++) -+ { -+ memset(rndbuf, 0, drbg_test_nopr[i].expectedlen); -+ ret = gcry_control(75, &drbg_test_nopr[i], NULL); -+ if(ret) -+ printf("CAVS test (nopr) FAILED %d, testdef %d\n", ret, i); -+ else -+ printf("CAVS test (nopr) PASSED, testdef %d\n", i); -+ result += ret; -+ } -+ -+ for(i = 0; ARRAY_SIZE(drbg_test_pr) > i; i++) -+ { -+ memset(rndbuf, 0, drbg_test_pr[i].expectedlen); -+ ret = gcry_control(75, &drbg_test_pr[i], NULL); -+ if(ret) -+ printf("CAVS test (pr) FAILED %d, testdef %d\n", ret, i); -+ else -+ printf("CAVS test (pr) PASSED, testdef %d\n", i); -+ result += ret; -+ } -+ -+ /* some failure catch tests */ -+ -+ /* there should be no SIGSEV -- if there is, test failed */ -+ gcry_randomize(NULL, ((1UL<<16) + 1), GCRY_STRONG_RANDOM); -+ printf("Test passed: not honoring large data request\n"); -+ -+ /* test automatic health check */ -+ memset(rndbuf, 0, 10); -+ ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_NOPR_CTRAES128, NULL, NULL); -+ for (i = 0; i <= (1<<10); i++) -+ gcry_randomize(rndbuf, 10, GCRY_STRONG_RANDOM); -+ printf("Test passed: retest tested\n"); -+ -+ /* Test for max personalization / addtl info string length not possible*/ -+ -+ if(result) -+ printf("completion of all tests FAILED\n"); -+ else -+ printf("completion of all tests: PASSED\n"); -+ -+} -+ -+static void generate_test(struct gcry_drbg_test_vector *test) -+{ -+ unsigned char *buf; -+#define DATALEN 10 -+ union { -+ unsigned char data[DATALEN]; -+ unsigned int data_int; -+ } u; -+ -+ memset(u.data, 0, DATALEN); -+ -+ -+ if (test && test->flags) -+ { -+ if (gcry_control(GCRYCTL_DRBG_REINIT, test->flags, NULL)) -+ { -+ printf("Test FAIL: re-init DRBG with test entropy\n"); -+ return; -+ } -+ } -+ while (1) -+ { -+ unsigned int len = 0; -+ gcry_randomize(u.data, DATALEN, GCRY_STRONG_RANDOM); -+ len = u.data_int & 0xfffff; -+ buf = malloc(len); -+ if(!buf) { -+ fprintf(stderr, "Cannot allocate %u bytes\n", len); -+ return; -+ } -+ -+ gcry_randomize(buf, len, GCRY_STRONG_RANDOM); -+ write(1, buf, len); -+ free (buf); -+ } -+} -+ -+static inline void * -+drbg_malloc (size_t len) -+{ -+ void *buf; -+ buf = malloc (len); -+ if (buf) -+ memset (buf, 0, len); -+ return buf; -+} -+ -+void hex2bin_m(char *in, unsigned char **out, size_t *len) -+{ -+ size_t tmplen = 0; -+ unsigned char *tmp; -+ -+ if (!in) -+ return; -+ -+ tmplen = strlen(in)/2; -+ if (0 > tmplen) -+ return; -+ if (tmplen * 2 != strlen(in)) -+ { -+ printf("odd number of characters which should be a hex string!\n"); -+ return; -+ } -+ -+ tmp = drbg_malloc(tmplen); -+ hex2bin(in, strlen(in), tmp, tmplen); -+ *out = tmp; -+ *len = tmplen; -+} -+ -+static void usage(void) -+{ -+ fprintf(stderr, "\nlibgcrypt DRBG test application\n\n"); -+ fprintf(stderr, "Usage:\n"); -+ fprintf(stderr, "\t-b\tInvoke builtin tests\n"); -+ fprintf(stderr, "\t-g\tGenerate random bits in given chunk size\n"); -+ fprintf(stderr, "\nThe following options are for CAVS testing\n"); -+ fprintf(stderr, "\t-f\tSet the DRBG selection flags - see gcrypt.h\n"); -+ fprintf(stderr, "\t-e\tEntropy string in HEX\n"); -+ fprintf(stderr, "\t-y\t1st Entropy PR string in HEX\n"); -+ fprintf(stderr, "\t-z\t2nd Entropy PR string in HEX\n"); -+ fprintf(stderr, "\t-c\t1st Additional intput string in HEX\n"); -+ fprintf(stderr, "\t-c\t2nd Additional intput string in HEX\n"); -+ fprintf(stderr, "\t-p\tPersonalization string in HEX\n"); -+ fprintf(stderr, "\t-l\tLength of requested random string in bytes\n"); -+ exit(1); -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int c = 0; -+ unsigned char *buf; -+ unsigned char *outbuf; -+ struct gcry_drbg_test_vector exttest; -+#define MAXDATA 256 -+ -+ memset(&exttest, 0, sizeof(struct gcry_drbg_test_vector)); -+ gcry_control (GCRYCTL_SET_VERBOSITY, 2); -+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); -+ if (!gcry_check_version ("1.5.0")) -+ die ("Libgcrypt is not sufficient enough\n"); -+ -+ /*gcry_control (GCRYCTL_DISABLE_SECMEM, 0);*/ -+ gcry_control (GCRYCTL_INIT_SECMEM, 1); -+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); -+ -+ while(1) -+ { -+ int opt_index = 0; -+ static struct option opts[] = -+ { -+ {"builtin", 0, 0, 0}, -+ {"gen", 0, 0, 0}, -+ {"flags", 1, 0, 0}, -+ {"entropy", 1, 0, 0}, -+ {"entpra", 1, 0, 0}, -+ {"entprb", 1, 0, 0}, -+ {"addtla", 1, 0, 0}, -+ {"addtlb", 1, 0, 0}, -+ {"pers", 1, 0, 0}, -+ {"len", 1, 0, 0}, -+ {0, 0, 0, 0} -+ }; -+ c = getopt_long(argc, argv, "bgf:e:y:z:c:d:p:l:", opts, &opt_index); -+ if(-1 == c) -+ break; -+ switch(c) -+ { -+ case 'b': -+ builtin_test(); -+ return 0; -+ case 'g': -+ generate_test(&exttest); -+ return 0; -+ case 'f': -+ exttest.flags = atoi(optarg); -+ break; -+ case 'e': -+ hex2bin_m(optarg, &exttest.entropy, &exttest.entropylen); -+ break; -+ case 'y': -+ hex2bin_m(optarg, &exttest.entpra, &exttest.entprlen); -+ break; -+ case 'z': -+ hex2bin_m(optarg, &exttest.entprb, &exttest.entprlen); -+ break; -+ case 'c': -+ hex2bin_m(optarg, &exttest.addtla, &exttest.addtllen); -+ break; -+ case 'd': -+ hex2bin_m(optarg, &exttest.addtlb, &exttest.addtllen); -+ break; -+ case 'p': -+ hex2bin_m(optarg, &exttest.pers, &exttest.perslen); -+ break; -+ case 'l': -+ exttest.expectedlen = atoi(optarg); -+ break; -+ default: -+ usage(); -+ } -+ } -+ -+ if (0 >= exttest.expectedlen) -+ usage(); -+ -+ buf = malloc(exttest.expectedlen); -+ if(!buf) { -+ fprintf(stderr, "Cannot allocate %li bytes\n", exttest.expectedlen); -+ return -1; -+ } -+ outbuf = malloc(exttest.expectedlen * 2 + 1); -+ if(!outbuf) { -+ fprintf(stderr, "Cannot allocate %li bytes\n", -+ (exttest.expectedlen*2+1)); -+ return -1; -+ } -+ memset(outbuf, 0, exttest.expectedlen * 2 + 1); -+ if (exttest.entropy) -+ gcry_control(75, &exttest, buf); -+ else -+ gcry_randomize(buf, exttest.expectedlen, GCRY_STRONG_RANDOM); -+ bin2hex(buf, exttest.expectedlen, -+ outbuf, exttest.expectedlen * 2 + 1, 0); -+ -+ printf("%s\n", outbuf); -+ -+ free(buf); -+ free(outbuf); -+ if(exttest.entropy) -+ free(exttest.entropy); -+ if(exttest.entpra) -+ free(exttest.entpra); -+ if(exttest.entprb) -+ free(exttest.entprb); -+ if(exttest.addtla) -+ free(exttest.addtla); -+ if(exttest.addtlb) -+ free(exttest.addtlb); -+ if(exttest.pers) -+ free(exttest.pers); -+ -+ gcry_control (GCRYCTL_TERM_SECMEM); -+ -+ return 0; -+} -+ -Index: libgcrypt-1.9.0/Makefile.am -=================================================================== ---- libgcrypt-1.9.0.orig/Makefile.am -+++ libgcrypt-1.9.0/Makefile.am -@@ -39,6 +39,14 @@ else - doc = - endif - -+bin_PROGRAMS = fipsdrv drbg_test -+ -+fipsdrv_SOURCES = tests/fipsdrv.c -+fipsdrv_LDADD = src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) -+ -+drbg_test_CPPFLAGS = -I../src -I$(top_srcdir)/src -+drbg_test_SOURCES = src/gcrypt.h tests/drbg_test.c -+drbg_test_LDADD = src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) - - DIST_SUBDIRS = m4 compat mpi cipher random src doc tests - SUBDIRS = compat mpi cipher random src $(doc) tests -@@ -51,6 +59,14 @@ EXTRA_DIST = autogen.sh autogen.rc READM - - DISTCLEANFILES = - -+bin_PROGRAMS = fipsdrv drbg_test -+ -+fipsdrv_SOURCES = tests/fipsdrv.c -+fipsdrv_LDADD = src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) -+ -+drbg_test_CPPFLAGS = -I../src -I$(top_srcdir)/src -+drbg_test_SOURCES = src/gcrypt.h tests/drbg_test.c -+drbg_test_LDADD = src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) - - # Add all the files listed in "distfiles" files to the distribution - dist-hook: gen-ChangeLog diff --git a/hwf.deny b/hwf.deny new file mode 100644 index 0000000..c030ceb --- /dev/null +++ b/hwf.deny @@ -0,0 +1,35 @@ +# This file can be used to globally disable the use of hardware +# based optimizations. Supported options are: + +# padlock-rng +# padlock-aes +# padlock-sha +# padlock-mmul +# intel-cpu +# intel-fast-shld +# intel-bmi2 +# intel-ssse3 +# intel-sse4.1 +# intel-pclmul +# intel-aesni +# intel-rdrand +# intel-avx +# intel-avx2 +# intel-fast-vpgather +# intel-rdtsc +# intel-shaext +# intel-vaes-vpclmul +# arm-neon +# arm-aes +# arm-sha1 +# arm-sha2 +# arm-pmull +# ppc-vcrypto +# ppc-arch_3_00 +# ppc-arch_2_07 +# ppc-arch_3_10 +# s390x-msa +# s390x-msa-4 +# s390x-msa-8 +# s390x-msa-9 +# s390x-vx diff --git a/libgcrypt-1.8.4-allow_FSM_same_state.patch b/libgcrypt-1.10.0-allow_FSM_same_state.patch similarity index 58% rename from libgcrypt-1.8.4-allow_FSM_same_state.patch rename to libgcrypt-1.10.0-allow_FSM_same_state.patch index 2ec4129..843cfea 100644 --- a/libgcrypt-1.8.4-allow_FSM_same_state.patch +++ b/libgcrypt-1.10.0-allow_FSM_same_state.patch @@ -1,8 +1,8 @@ -Index: libgcrypt-1.8.4/src/fips.c +Index: libgcrypt-1.10.0/src/fips.c =================================================================== ---- libgcrypt-1.8.4.orig/src/fips.c -+++ libgcrypt-1.8.4/src/fips.c -@@ -930,6 +930,10 @@ fips_new_state (enum module_states new_s +--- libgcrypt-1.10.0.orig/src/fips.c ++++ libgcrypt-1.10.0/src/fips.c +@@ -890,6 +890,10 @@ fips_new_state (enum module_states new_s } diff --git a/libgcrypt-out-of-core-handler.patch b/libgcrypt-1.10.0-out-of-core-handler.patch similarity index 52% rename from libgcrypt-out-of-core-handler.patch rename to libgcrypt-1.10.0-out-of-core-handler.patch index e7cd22a..8769e4c 100644 --- a/libgcrypt-out-of-core-handler.patch +++ b/libgcrypt-1.10.0-out-of-core-handler.patch @@ -1,8 +1,8 @@ -Index: libgcrypt-1.9.4/src/global.c +Index: libgcrypt-1.10.0/src/global.c =================================================================== ---- libgcrypt-1.9.4.orig/src/global.c -+++ libgcrypt-1.9.4/src/global.c -@@ -951,7 +951,6 @@ _gcry_set_outofcore_handler (int (*f)(vo +--- libgcrypt-1.10.0.orig/src/global.c ++++ libgcrypt-1.10.0/src/global.c +@@ -974,7 +974,6 @@ _gcry_set_outofcore_handler (int (*f)(vo if (fips_mode () ) { diff --git a/libgcrypt-1.10.0-use-fipscheck.patch b/libgcrypt-1.10.0-use-fipscheck.patch new file mode 100644 index 0000000..ef1d5f9 --- /dev/null +++ b/libgcrypt-1.10.0-use-fipscheck.patch @@ -0,0 +1,114 @@ +Index: libgcrypt-1.10.1/src/fips.c +=================================================================== +--- libgcrypt-1.10.1.orig/src/fips.c ++++ libgcrypt-1.10.1/src/fips.c +@@ -949,6 +949,65 @@ hmac256_check (const char *filename, con + return err; + } + ++static int ++get_library_path(const char *libname, const char *symbolname, ++ char *path, size_t pathlen) ++{ ++ Dl_info info; ++ void *dl, *sym; ++ int rv = -1; ++ ++ dl = dlopen(libname, RTLD_LAZY); ++ if (dl == NULL) ++ return -1; ++ ++ sym = dlsym(dl, symbolname); ++ if (sym != NULL && dladdr(sym, &info)) ++ { ++ strncpy(path, info.dli_fname, pathlen-1); ++ path[pathlen-1] = '\0'; ++ rv = 0; ++ } ++ ++ dlclose(dl); ++ ++ return rv; ++} ++ ++static gpg_error_t ++get_hmac_path(char **fname, char *suffix) ++{ ++ char libpath[4096]; ++ gpg_error_t err; ++ ++ if (get_library_path ("libgcrypt.so.20", "gcry_check_version", ++ libpath, sizeof(libpath))) ++ err = gpg_error_from_syserror (); ++ else ++ { ++ *fname = _gcry_malloc (strlen (libpath) + 1 + 5 + 1 ); ++ if (!*fname) ++ err = gpg_error_from_syserror (); ++ else ++ { ++ char *p; ++ ++ /* Prefix the basename with a dot. */ ++ strcpy (*fname, libpath); ++ p = strrchr (*fname, '/'); ++ if (p) ++ p++; ++ else ++ p = *fname; ++ memmove (p+1, p, strlen (p)+1); ++ *p = '.'; ++ strcat (*fname, suffix); ++ err = 0; ++ } ++ } ++ return err; ++} ++ + /* Run an integrity check on the binary. Returns 0 on success. */ + static int + check_binary_integrity (void) +@@ -997,6 +1056,33 @@ run_hmac_sha256_selftests (int extended) + } + #endif + ++int ++can_skip_selftests(void) ++{ ++ char *fname = NULL; ++ int ret = 0; ++ ++ if (fips_mode()) ++ return 0; ++ ++ if (get_hmac_path(&fname, ".fips")) ++ return 0; ++ ++ /* check the hmac presence */ ++ if (access(fname, F_OK)) ++ /* no hmac file is present, don't run the tests */ ++ if (errno == ENOENT) ++ ret = 1; ++ /* otherwise one of these events happened: ++ * access() returned 0 ++ * -> run the tests ++ * some error other than ENOENT occurred ++ * -> run the tests anyway and let them fail ++ */ ++ ++ xfree(fname); ++ return ret; ++} + + /* Run the self-tests. If EXTENDED is true, extended versions of the + selftest are run, that is more tests than required by FIPS. */ +@@ -1006,6 +1092,9 @@ _gcry_fips_run_selftests (int extended) + enum module_states result = STATE_ERROR; + gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED; + ++ if (can_skip_selftests()) ++ return 0; ++ + if (fips_mode ()) + fips_new_state (STATE_SELFTEST); + diff --git a/libgcrypt-1.10.1.tar.bz2 b/libgcrypt-1.10.1.tar.bz2 new file mode 100644 index 0000000..7dccb2d --- /dev/null +++ b/libgcrypt-1.10.1.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef14ae546b0084cd84259f61a55e07a38c3b53afc0f546bffcef2f01baffe9de +size 3778457 diff --git a/libgcrypt-1.10.1.tar.bz2.sig b/libgcrypt-1.10.1.tar.bz2.sig new file mode 100644 index 0000000000000000000000000000000000000000000000000000000000000000..1798eb3229061cb3bbf0ae7b18d99ad4d0b087ca0a03945e79d26a57600c0914 GIT binary patch literal 238 zcmeAuWnmEGV2~A4WXWBXm$E!p!y#PSlPRcU`VKV*t6Qv0Nsjv;FmQ1Sz(kl^7#TJd zylDS$$Lxvm%=>$bm&I_YIM`2r&@$&)*v-a!PR9%c85uUOT)t-NDvSS8CWe`2E2Jkz z>E-LS7rb77>F^xQi@6^;I}p~c=@X3pZl~Mp{%a=3%f8vVlE+T$1zPLBC=_HZOyuTz zhW|B=>wTTJM>iG)L|)o>r)#~j^v$?C@ePT$&8q?eSFK#a$ndvfx&L&PLW|G~9 -+# Werner Koch (libgcrypt interface) -+# Tomas Mraz (addition of DSA2) - # Copyright (c) atsec information security corporation - # - # Permission is hereby granted, free of charge, to any person obtaining a copy -@@ -85,13 +87,16 @@ - # T[CBC|CFB??|ECB|OFB]varkey - # T[CBC|CFB??|ECB|OFB]invperm - # T[CBC|CFB??|ECB|OFB]vartext -+# WARNING: TDES in CFB and OFB mode problems see below - # - # ANSI X9.31 RNG - # ANSI931_AES128MCT - # ANSI931_AES128VST - # --# DSA -+# DSA2 - # PQGGen -+# PQGVer -+# KeyPair - # SigGen - # SigVer - # -@@ -101,6 +106,36 @@ - # RC4PltBD - # RC4REGT - # -+# -+# TDES MCT for CFB and OFB: -+# ------------------------- -+# The inner loop cannot be handled by this script. If you want to have tests -+# for these cipher types, implement your own inner loop and add it to -+# crypto_mct. -+# -+# the value $next_source in crypto_mct is NOT set by the standard implementation -+# of this script. It would need to be set as follows for these two (code take -+# from fipsdrv.c from libgcrypt - the value input at the end will contain the -+# the value for $next_source: -+# -+# ... inner loop ... -+# ... -+# get_current_iv (hd, last_iv, blocklen); -+# ... encrypt / decrypt (input is the data to be en/decrypted and output is the -+# result of operation) ... -+# if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB)) -+# memcpy (input, last_iv, blocklen); -+# else if (cipher_mode == GCRY_CIPHER_MODE_OFB) -+# memcpy (input, last_iv, blocklen); -+# else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) -+# { -+# /* Reconstruct the output vector. */ -+# int i; -+# for (i=0; i < blocklen; i++) -+# input[i] ^= output[i]; -+# } -+# ... inner loop ends ... -+# ==> now, the value of input is to be put into $next_source - - use strict; - use warnings; -@@ -226,6 +261,8 @@ my $hmac; - # Generate the P, Q, G, Seed, counter, h (value used to generate g) values - # for DSA - # $1: modulus size -+# $2: q size -+# $3: seed (might be empty string) - # return: string with the calculated values in hex format, where each value - # is separated from the previous with a \n in the following order: - # P\n -@@ -236,6 +273,19 @@ my $hmac; - # h - my $dsa_pqggen; - -+# Generate the G value from P and Q -+# for DSA -+# $1: modulus size -+# $2: q size -+# $3: P in hex form -+# $4: Q in hex form -+# return: string with the calculated values in hex format, where each value -+# is separated from the previous with a \n in the following order: -+# P\n -+# Q\n -+# G\n -+my $dsa_ggen; -+ - # - # Generate an DSA public key from the provided parameters: - # $1: Name of file to create -@@ -255,10 +305,20 @@ my $dsa_verify; - - # generate a new DSA key with the following properties: - # PEM format --# $1 keyfile name --# return: file created, hash with keys of P, Q, G in hex format -+# $1: modulus size -+# $2: q size -+# $3 keyfile name -+# return: file created with key, string with values of P, Q, G in hex format - my $gen_dsakey; - -+# generate a new DSA private key XY parameters in domain: -+# PEM format -+# $1: P in hex form -+# $2: Q in hex form -+# $3: G in hex form -+# return: string with values of X, Y in hex format -+my $gen_dsakey_domain; -+ - # Sign a message with DSA - # $1: data to be signed in hex form - # $2: Key file in PEM format with the private key -@@ -500,17 +560,32 @@ sub libgcrypt_hmac($$$$) { - return pipe_through_program($msg, $program); - } - --sub libgcrypt_dsa_pqggen($) { -+sub libgcrypt_dsa_pqggen($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $seed = shift; -+ -+ my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; -+ return pipe_through_program($seed, $program); -+} -+ -+sub libgcrypt_dsa_ggen($$$$) { - my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $domain = "(domain (p #$p#)(q #$q#))"; - -- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; - return pipe_through_program("", $program); - } - --sub libgcrypt_gen_dsakey($) { -+sub libgcrypt_gen_dsakey($$$) { -+ my $mod = shift; -+ my $qsize = shift; - my $file = shift; - -- my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key $file dsa-gen"; - my $tmp; - my %ret; - -@@ -519,10 +594,21 @@ sub libgcrypt_gen_dsakey($) { - $tmp = pipe_through_program("", $program); - die "dsa key gen failed: file $file not created" if (! -f $file); - -- @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); -+ @ret{'P', 'Q', 'G'} = split(/\n/, $tmp); - return %ret; - } - -+sub libgcrypt_gen_dsakey_domain($$$) { -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $domain = "(domain (p #$p#)(q #$q#)(g #$g#))"; -+ -+ my $program = "fipsdrv --key '$domain' dsa-gen-key"; -+ -+ return pipe_through_program("", $program); -+} -+ - sub libgcrypt_dsa_genpubkey($$$$$) { - my $filename = shift; - my $p = shift; -@@ -1139,7 +1225,7 @@ sub hmac_kat($$$$) { - $out .= "Tlen = $tlen\n"; - $out .= "Key = $key\n"; - $out .= "Msg = $msg\n"; -- $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; -+ $out .= "Mac = " . lc(&$hmac($key, $tlen, $msg, $hashtype{$tlen})) . "\n"; - - return $out; - } -@@ -1205,7 +1291,7 @@ sub crypto_mct($$$$$$$$) { - } - my ($CO, $CI); - my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); -- $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/); -+ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/ && defined($state_cipher_des)); - my $pid = open2($CO, $CI, $cipher_imp); - - my $calc_data = $iv; # CT[j] -@@ -1213,8 +1299,8 @@ sub crypto_mct($$$$$$$$) { - my $old_old_calc_data; # CT[j-2] - my $next_source; - -- # TDES inner loop implements logic within driver -- if ($cipher =~ /des/) { -+ # TDES inner loop implements logic within driver of libgcrypt -+ if ($cipher =~ /des/ && $opt{'I'} && $opt{'I'} eq 'libgcrypt' ) { - # Need to provide a dummy IV in case of ECB mode. - my $iv_arg = (defined($iv) && $iv ne "") - ? bin2hex($iv) -@@ -1238,6 +1324,10 @@ sub crypto_mct($$$$$$$$) { - $line = <$CO>; - } else { - for (my $j = 0; $j < $iloop; ++$j) { -+ if ($cipher =~ /des-ede3-ofb/ || -+ (!$enc && $cipher =~ /des-ede3-cfb/)) { -+ die "Implementation lacks support for TDES OFB and TDES CFB in encryption mode - the problem is that we would need to extract the IV of the last round of encryption which would be the input for the next round - see comments in this script for implementation requirements"; -+ } - $old_old_calc_data = $old_calc_data; - $old_calc_data = $calc_data; - -@@ -1503,21 +1593,23 @@ sub rngx931($$$$) { - return $out; - } - --# DSA PQGGen test -+# DSA PQGen test - # $1 modulus size --# $2 number of rounds to perform the test -+# $2 q size -+# $3 number of rounds to perform the test - # return: string formatted as expected by CAVS --sub dsa_pqggen_driver($$) { -+sub dsa_pqgen_driver($$$) { - my $mod = shift; -+ my $qsize = shift; - my $rounds = shift; - - my $out = ""; - for(my $i=0; $i<$rounds; $i++) { -- my $ret = &$dsa_pqggen($mod); -+ my $ret = &$dsa_pqggen($mod, $qsize, ""); - my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); -- die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" -- if (!defined($P) || !defined($Q) || !defined($G) || -- !defined($Seed) || !defined($c) || !defined($H)); -+ die "Return value does not contain all expected values of P, Q, Seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || -+ !defined($Seed) || !defined($c)); - - # now change the counter to decimal as CAVS wants decimal - # counter value although all other is HEX -@@ -1525,15 +1617,166 @@ sub dsa_pqggen_driver($$) { - - $out .= "P = $P\n"; - $out .= "Q = $Q\n"; -- $out .= "G = $G\n"; -- $out .= "Seed = $Seed\n"; -- $out .= "c = $c\n"; -- $out .= "H = $H\n\n"; -+ $out .= "domain_parameter_seed = $Seed\n"; -+ $out .= "counter = $c\n\n"; - } - - return $out; - } - -+# DSA GGen test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# return: string formatted as expected by CAVS -+sub dsa_ggen_driver($$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_ggen($mod, $qsize, $p, $q); -+ my ($P, $Q, $G) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G for dsa_ggen" -+ if (!defined($P) || !defined($Q) || !defined($G)); -+ -+ $out .= "G = $G\n\n"; -+ -+ return $out; -+} -+ -+sub hexcomp($$) { -+ my $a = lc shift; -+ my $b = lc shift; -+ -+ if (length $a < length $b) { -+ my $c = $a; -+ $a = $b; -+ $b = $a; -+ } -+ -+ while (length $b < length $a) { -+ $b = "00$b"; -+ } -+ -+ return $a eq $b; -+} -+ -+# DSA PQVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 seed in hex form -+# $6 c decimal counter -+# return: string formatted as expected by CAVS -+sub dsa_pqver_driver($$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $seed = shift; -+ my $c = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2)); -+ -+ $c2 = hex($c2); -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($seed, $seed2) && $c == $c2) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ return $out; -+} -+ -+# DSA PQGVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 g in hex form -+# $6 seed in hex form -+# $7 c decimal counter -+# $8 h in hex form -+# return: string formatted as expected by CAVS -+sub dsa_pqgver_driver($$$$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $seed = shift; -+ my $c = shift; -+ my $h = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c, H for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2) || !defined($h2)); -+ -+ -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ $out .= "H = $h\n"; -+ -+ $c2 = hex($c2); -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($G, $g) && hexcomp($seed, $seed2) && -+ $c == $c2 && hex($h) == hex($h2)) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ -+ return $out; -+} -+ -+# DSA Keypair test -+# $1 modulus size -+# $2 q size -+# $3 number of rounds to perform the test -+# return: string formatted as expected by CAVS -+sub dsa_keypair_driver($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $rounds = shift; -+ -+ my $out = ""; -+ my $tmpkeyfile = "dsa_siggen.tmp.$$"; -+ my %pqg = &$gen_dsakey($mod, $qsize, $tmpkeyfile); -+ $out .= "P = " . $pqg{'P'} . "\n"; -+ $out .= "Q = " . $pqg{'Q'} . "\n"; -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ unlink($tmpkeyfile); -+ -+ for(my $i=0; $i<$rounds; $i++) { -+ my $ret = &$gen_dsakey_domain($pqg{'P'}, $pqg{'Q'}, $pqg{'G'}); -+ my ($X, $Y) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of X, Y for gen_dsakey_domain" -+ if (!defined($X) || !defined($Y)); -+ -+ $out .= "X = $X\n"; -+ $out .= "Y = $Y\n\n"; -+ } -+ -+ return $out; -+} - - # DSA SigGen test - # $1: Message to be signed in hex form -@@ -1658,12 +1901,16 @@ sub parse($$) { - my $klen = ""; - my $tlen = ""; - my $modulus = ""; -+ my $qsize = ""; - my $capital_n = 0; -+ my $num = 0; - my $capital_p = ""; - my $capital_q = ""; - my $capital_g = ""; - my $capital_y = ""; - my $capital_r = ""; -+ my $capital_h = ""; -+ my $c = ""; - my $xp1 = ""; - my $xp2 = ""; - my $Xp = ""; -@@ -1700,7 +1947,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/) { $mode="cbc"; } - elsif ($tmpline =~ /ECB/) { $mode="ecb"; } - elsif ($tmpline =~ /OFB/) { $mode="ofb"; } -@@ -1749,7 +1996,15 @@ sub parse($$) { - - if ($tt == 0) { - ##### Identify the test type -- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { -+ if ($tmpline =~ /PQGVer/) { -+ $tt = 16; -+ die "Interface function for DSA PQGVer testing not defined for tested library" -+ if (!defined($dsa_pqggen)); -+ } elsif ($tmpline =~ /KeyPair/) { -+ $tt = 14; -+ die "Interface function dsa_keygen for DSA key generation not defined for tested library" -+ if (!defined($gen_dsakey_domain)); -+ } elsif ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { - $tt = 13; - die "Interface function rsa_derive for RSA key generation not defined for tested library" - if (!defined($rsa_derive)); -@@ -1760,11 +2015,11 @@ sub parse($$) { - } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { - $tt = 11; - die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" -- if (!defined($dsa_sign) || !defined($gen_rsakey)); -+ if (!defined($dsa_sign) || !defined($gen_dsakey)); - } elsif ($tmpline =~ /PQGGen/) { - $tt = 10; - die "Interface function for DSA PQGGen testing not defined for tested library" -- if (!defined($dsa_pqggen)); -+ if (!defined($dsa_pqggen) || !defined($dsa_ggen)); - } elsif ($tmpline =~ /Hash sizes tested/) { - $tt = 9; - die "Interface function hmac for HMAC testing not defined for tested library" -@@ -1792,7 +2047,7 @@ sub parse($$) { - } elsif ($tmpline =~ /Monte|MCT|Carlo/) { - $tt = 2; - die "Interface function state_cipher for Stateful Cipher operation defined for tested library" -- if (!defined($state_cipher) || !defined($state_cipher_des)); -+ if (!defined($state_cipher) && !defined($state_cipher_des)); - } elsif ($cipher =~ /^sha/) { - $tt = 3; - die "Interface function hash for Hashing not defined for tested library" -@@ -1875,18 +2130,44 @@ sub parse($$) { - die "Msg/Seed seen twice - input file crap" if ($pt ne ""); - $pt=$2; - } -- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ elsif ($line =~ /^\[A.2.1\s.*\]$/) { # found in DSA2 PQGGen request -+ $out .= $line . "\n"; # print it -+ if ($tt == 10) { -+ # now generate G from PQ -+ $tt = 15; -+ } -+ } -+ elsif ($line =~ /^\[A.2.2\s.*\]$/) { # found in DSA2 PQGVer request -+ $out .= $line . "\n"; # print it -+ if ($tt == 16) { -+ # now verify PQG -+ $tt = 17; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*L=([0-9]*),\s*N=([0-9]*).*\]$/) { # found in DSA2 requests - $modulus = $1; -+ $qsize = $2; - $out .= $line . "\n\n"; # print it -+ # clear eventual PQG -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; - # generate the private key with given bit length now - # as we have the required key length in bit - if ($tt == 11) { - $dsa_keyfile = "dsa_siggen.tmp.$$"; -- my %pqg = &$gen_dsakey($dsa_keyfile); -+ my %pqg = &$gen_dsakey($modulus, $qsize, $dsa_keyfile); - $out .= "P = " . $pqg{'P'} . "\n"; - $out .= "Q = " . $pqg{'Q'} . "\n"; -- $out .= "G = " . $pqg{'G'} . "\n"; -- } elsif ( $tt == 5 ) { -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ $modulus = $1; -+ $out .= $line . "\n\n"; # print it -+ # generate the private key with given bit length now -+ # as we have the required key length in bit -+ if ( $tt == 5 ) { - # XXX maybe a secure temp file name is better here - # but since it is not run on a security sensitive - # system, I hope that this is fine -@@ -1932,11 +2213,16 @@ sub parse($$) { - if ($tlen ne ""); - $tlen=$1; - } -- elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen -+ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair - die "N seen twice - check input file" - if ($capital_n); - $capital_n = $1; - } -+ elsif ($line =~ /^Num\s*=\s*(.*)/) { #DSA PQGGen -+ die "Num seen twice - check input file" -+ if ($num); -+ $num = $1; -+ } - elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer - die "P seen twice - check input file" - if ($capital_p); -@@ -1965,6 +2251,16 @@ sub parse($$) { - if ($capital_r); - $capital_r = $1; - } -+ elsif ($line =~ /^H\s*=\s*(.*)/) { #DSA PQGVer -+ die "H seen twice - check input file" -+ if ($capital_h); -+ $capital_h = $1; -+ } -+ elsif ($line =~ /^c\s*=\s*(.*)/) { #DSA PQGVer -+ die "c seen twice - check input file" -+ if ($c); -+ $c = $1; -+ } - elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen - die "xp1 seen twice - check input file" - if ($xp1); -@@ -2074,11 +2370,10 @@ sub parse($$) { - } - } - elsif ($tt == 10) { -- if ($modulus ne "" && $capital_n > 0) { -- $out .= dsa_pqggen_driver($modulus, $capital_n); -- #$mod is not resetted -- $capital_n = 0; -- } -+ if ($modulus ne "" && $qsize ne "" && $num > 0) { -+ $out .= dsa_pqgen_driver($modulus, $qsize, $num); -+ $num = 0; -+ } - } - elsif ($tt == 11) { - if ($pt ne "" && $dsa_keyfile ne "") { -@@ -2141,6 +2436,74 @@ sub parse($$) { - $Xq = ""; - } - } -+ elsif ($tt == 14) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_n > 0) { -+ $out .= dsa_keypair_driver($modulus, -+ $qsize, -+ $capital_n); -+ $capital_n = 0; -+ } -+ } -+ elsif ($tt == 15) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "") { -+ $out .= dsa_ggen_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q); -+ $capital_p = ""; -+ $capital_q = ""; -+ $num--; -+ } -+ } -+ elsif ($tt == 16) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $pt ne "" && -+ $c ne "") { -+ $out .= dsa_pqver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $pt, -+ $c); -+ $capital_p = ""; -+ $capital_q = ""; -+ $pt = ""; -+ $c = ""; -+ } -+ } -+ elsif ($tt == 17) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $capital_g ne "" && -+ $pt ne "" && -+ $c ne "" && -+ $capital_h ne "") { -+ $out .= dsa_pqgver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $capital_g, -+ $pt, -+ $c, -+ $capital_h); -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; -+ $pt = ""; -+ $c = ""; -+ $capital_h = ""; -+ } -+ } - elsif ($tt > 0) { - die "Test case $tt not defined"; - } -@@ -2199,7 +2562,9 @@ sub main() { - $state_rng = \&libgcrypt_state_rng; - $hmac = \&libgcrypt_hmac; - $dsa_pqggen = \&libgcrypt_dsa_pqggen; -+ $dsa_ggen = \&libgcrypt_dsa_ggen; - $gen_dsakey = \&libgcrypt_gen_dsakey; -+ $gen_dsakey_domain = \&libgcrypt_gen_dsakey_domain; - $dsa_sign = \&libgcrypt_dsa_sign; - $dsa_verify = \&libgcrypt_dsa_verify; - $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; -Index: libgcrypt-1.7.2/tests/cavs_tests.sh -=================================================================== ---- libgcrypt-1.7.2.orig/tests/cavs_tests.sh -+++ libgcrypt-1.7.2/tests/cavs_tests.sh -@@ -55,7 +55,7 @@ function run_one_test () { - [ -d "$respdir" ] || mkdir "$respdir" - [ -f "$rspfile" ] && rm "$rspfile" - -- if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then -+ if echo "$reqfile" | grep '/DSA.\?/req/' >/dev/null 2>/dev/null; then - dflag="-D" - fi - -Index: libgcrypt-1.7.2/tests/fipsdrv.c -=================================================================== ---- libgcrypt-1.7.2.orig/tests/fipsdrv.c -+++ libgcrypt-1.7.2/tests/fipsdrv.c -@@ -892,6 +892,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) - die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); - - p = buf; -+ while (*p) -+ *p++ = tolower(*p); -+ p = buf; - if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) - p += 2; - -@@ -1765,14 +1768,14 @@ run_rsa_verify (const void *data, size_t - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen (int keysize) -+dsa_gen (int keysize, int qsize) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; - - err = gcry_sexp_build (&keyspec, NULL, -- "(genkey (dsa (nbits %d)(use-fips186-2)))", -- keysize); -+ "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)))", -+ keysize, qsize); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1790,7 +1793,7 @@ dsa_gen (int keysize) - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) -+dsa_gen_with_seed (int keysize, int qsize, const void *seed, size_t seedlen) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; -@@ -1799,10 +1802,11 @@ dsa_gen_with_seed (int keysize, const vo - "(genkey" - " (dsa" - " (nbits %d)" -- " (use-fips186-2)" -+ " (qbits %d)" -+ " (use-fips186)" - " (derive-parms" - " (seed %b))))", -- keysize, (int)seedlen, seed); -+ keysize, qsize, (int)seedlen, seed); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1810,6 +1814,37 @@ dsa_gen_with_seed (int keysize, const vo - err = gcry_pk_genkey (&key, keyspec); - if (err) - die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); -+ -+ gcry_sexp_release (keyspec); -+ -+ return key; -+} -+ -+/* Generate a DSA key with specified domain parameters and return the complete -+ S-expression. */ -+static gcry_sexp_t -+dsa_gen_key (const char *domain) -+{ -+ gpg_error_t err; -+ gcry_sexp_t keyspec, key, domspec; -+ -+ err = gcry_sexp_new (&domspec, domain, strlen(domain), 0); -+ if (err) -+ die ("gcry_sexp_build failed for domain spec: %s\n", -+ gpg_strerror (err)); -+ -+ err = gcry_sexp_build (&keyspec, NULL, -+ "(genkey" -+ " (dsa" -+ " (use-fips186)" -+ " %S))", -+ domspec); -+ if (err) -+ die ("gcry_sexp_build failed for DSA key generation: %s\n", -+ gpg_strerror (err)); -+ err = gcry_pk_genkey (&key, keyspec); -+ if (err) -+ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); - - gcry_sexp_release (keyspec); - -@@ -1849,7 +1884,7 @@ ecdsa_gen_key (const char *curve) - with one parameter per line in hex format using this order: p, q, - g, seed, counter, h. */ - static void --print_dsa_domain_parameters (gcry_sexp_t key) -+print_dsa_domain_parameters (gcry_sexp_t key, int print_misc) - { - gcry_sexp_t l1, l2; - gcry_mpi_t mpi; -@@ -1885,6 +1920,9 @@ print_dsa_domain_parameters (gcry_sexp_t - } - gcry_sexp_release (l1); - -+ if (!print_misc) -+ return; -+ - /* Extract the seed values. */ - l1 = gcry_sexp_find_token (key, "misc-key-info", 0); - if (!l1) -@@ -1976,38 +2014,106 @@ print_ecdsa_dq (gcry_sexp_t key) - } - - --/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+/* Print just the XY private key parameters. KEY -+ is the complete key as returned by dsa_gen. We print to stdout -+ with one parameter per line in hex format using this order: x, y. */ -+static void -+print_dsa_xy (gcry_sexp_t key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t mpi; -+ int idx; -+ -+ l1 = gcry_sexp_find_token (key, "private-key", 0); -+ if (!l1) -+ die ("private key not found in genkey result\n"); -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("returned private key not formed as expected\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ /* Extract the parameters from the S-expression and print them to stdout. */ -+ for (idx=0; "xy"[idx]; idx++) -+ { -+ l2 = gcry_sexp_find_token (l1, "xy"+idx, 1); -+ if (!l2) -+ die ("no %c parameter in returned public key\n", "xy"[idx]); -+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); -+ if (!mpi) -+ die ("no value for %c parameter in returned private key\n","xy"[idx]); -+ gcry_sexp_release (l2); -+ if (standalone_mode) -+ printf ("%c = ", "XY"[idx]); -+ print_mpi_line (mpi, 1); -+ gcry_mpi_release (mpi); -+ } -+ -+ gcry_sexp_release (l1); -+} -+ -+ -+/* Generate DSA pq domain parameters for a modulus size of KEYSIZE. The - result is printed to stdout with one parameter per line in hex -- format and in this order: p, q, g, seed, counter, h. If SEED is -+ format and in this order: p, q, seed, counter. If SEED is - not NULL this seed value will be used for the generation. */ - static void --run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) -+run_dsa_pqg_gen (int keysize, int qsize, const void *seed, size_t seedlen) - { - gcry_sexp_t key; - - if (seed) -- key = dsa_gen_with_seed (keysize, seed, seedlen); -+ key = dsa_gen_with_seed (keysize, qsize, seed, seedlen); - else -- key = dsa_gen (keysize); -- print_dsa_domain_parameters (key); -+ key = dsa_gen (keysize, qsize); -+ print_dsa_domain_parameters (key, 1); -+ gcry_sexp_release (key); -+} -+ -+ -+/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+ result is printed to stdout with one parameter per line in hex -+ format and in this order: p, q, g, seed, counter, h. If SEED is -+ not NULL this seed value will be used for the generation. */ -+static void -+run_dsa_g_gen (int keysize, int qsize, const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_domain_parameters (key, 0); -+ gcry_sexp_release (key); -+} -+ -+/* Generate a DSA key with specified domain parameters -+ and print the XY values. */ -+static void -+run_dsa_gen_key (const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_xy (key); -+ - gcry_sexp_release (key); - } - - - /* Generate a DSA key of size of KEYSIZE and write the private key to - FILENAME. Also write the parameters to stdout in the same way as -- run_dsa_pqg_gen. */ -+ run_dsa_g_gen. */ - static void --run_dsa_gen (int keysize, const char *filename) -+run_dsa_gen (int keysize, int qsize, const char *filename) - { - gcry_sexp_t key, private_key; - FILE *fp; - -- key = dsa_gen (keysize); -+ key = dsa_gen (keysize, qsize); - private_key = gcry_sexp_find_token (key, "private-key", 0); - if (!private_key) - die ("private key not found in genkey result\n"); -- print_dsa_domain_parameters (key); -+ print_dsa_domain_parameters (key, 1); - - fp = fopen (filename, "wb"); - if (!fp) -@@ -2020,6 +2126,53 @@ run_dsa_gen (int keysize, const char *fi - } - - -+static int -+dsa_hash_from_key(gcry_sexp_t s_key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t q; -+ unsigned int qbits; -+ -+ l1 = gcry_sexp_find_token (s_key, "public-key", 0); -+ if (!l1) -+ { -+ l1 = gcry_sexp_find_token (s_key, "private-key", 0); -+ if (!l1) -+ die ("neither private nor public key found in the loaded key\n"); -+ } -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("public key not formed as expected - no dsa\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ l2 = gcry_sexp_find_token (l1, "q", 0); -+ if (!l2) -+ die ("public key not formed as expected - no q\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); -+ if (!q) -+ die ("public key not formed as expected - no mpi in q\n"); -+ qbits = gcry_mpi_get_nbits(q); -+ gcry_sexp_release(l1); -+ gcry_mpi_release(q); -+ switch(qbits) -+ { -+ case 160: -+ return GCRY_MD_SHA1; -+ case 224: -+ return GCRY_MD_SHA224; -+ case 256: -+ return GCRY_MD_SHA256; -+ default: -+ die("bad number bits (%d) of q in key\n", qbits); -+ } -+ return GCRY_MD_NONE; -+} -+ - - /* Sign DATA of length DATALEN using the key taken from the S-expression - encoded KEYFILE. */ -@@ -2029,11 +2182,16 @@ run_dsa_sign (const void *data, size_t d - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; -+ -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ gcry_md_hash_buffer (algo, hash, data, datalen); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -2044,8 +2202,6 @@ run_dsa_sign (const void *data, size_t d - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); -- - err = gcry_pk_sign (&s_sig, s_data, s_key); - if (err) - { -@@ -2121,13 +2277,18 @@ run_dsa_verify (const void *data, size_t - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); -+ -+ gcry_md_hash_buffer (algo, hash, data, datalen); - /* Note that we can't simply use %b with HASH to build the - S-expression, because that might yield a negative value. */ -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -2138,7 +2299,6 @@ run_dsa_verify (const void *data, size_t - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); - s_sig = read_sexp_from_file (sigfile); - - err = gcry_pk_verify (s_sig, s_data, s_key); -@@ -2304,7 +2464,7 @@ usage (int show_help) - "MODE:\n" - " encrypt, decrypt, digest, random, hmac-sha,\n" - " rsa-{derive,gen,sign,verify},\n" -- " dsa-{pqg-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" -+ " dsa-{pq-gen,g-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" - "OPTIONS:\n" - " --verbose Print additional information\n" - " --binary Input and output is in binary form\n" -@@ -2315,6 +2475,7 @@ usage (int show_help) - " --algo NAME Use algorithm NAME\n" - " --curve NAME Select ECC curve spec NAME\n" - " --keysize N Use a keysize of N bits\n" -+ " --qize N Use a DSA q parameter size of N bits\n" - " --signature NAME Take signature from file NAME\n" - " --chunk N Read in chunks of N bytes (implies --binary)\n" - " --pkcs1 Use PKCS#1 encoding\n" -@@ -2344,6 +2505,7 @@ main (int argc, char **argv) - const char *dt_string = NULL; - const char *algo_string = NULL; - const char *keysize_string = NULL; -+ const char *qsize_string = NULL; - const char *signature_string = NULL; - FILE *input; - void *data; -@@ -2437,6 +2599,14 @@ main (int argc, char **argv) - keysize_string = *argv; - argc--; argv++; - } -+ else if (!strcmp (*argv, "--qsize")) -+ { -+ argc--; argv++; -+ if (!argc) -+ usage (0); -+ qsize_string = *argv; -+ argc--; argv++; -+ } - else if (!strcmp (*argv, "--signature")) - { - argc--; argv++; -@@ -2792,23 +2962,49 @@ main (int argc, char **argv) - } - else if (!strcmp (mode_string, "dsa-pqg-gen")) - { -- int keysize; -+ int keysize, qsize; -+ -+ keysize = keysize_string? atoi (keysize_string) : 0; -+ if (keysize < 1024 || keysize > 3072) -+ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ run_dsa_pqg_gen (keysize, qsize, datalen? data:NULL, datalen); -+ } -+ else if (!strcmp (mode_string, "dsa-g-gen")) -+ { -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ if (!key_string) -+ die ("option --key containing pq domain parameters is required in this mode\n"); -+ run_dsa_g_gen (keysize, qsize, key_string); -+ } -+ else if (!strcmp (mode_string, "dsa-gen-key")) -+ { -+ if (!key_string) -+ die ("option --key containing pqg domain parameters is required in this mode\n"); -+ run_dsa_gen_key (key_string); - } - else if (!strcmp (mode_string, "dsa-gen")) - { -- int keysize; -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); - if (!key_string) - die ("option --key is required in this mode\n"); -- run_dsa_gen (keysize, key_string); -+ run_dsa_gen (keysize, qsize, key_string); - } - else if (!strcmp (mode_string, "dsa-sign")) - { diff --git a/libgcrypt-1.6.1-use-fipscheck.patch b/libgcrypt-1.6.1-use-fipscheck.patch deleted file mode 100644 index 49cf2d7..0000000 --- a/libgcrypt-1.6.1-use-fipscheck.patch +++ /dev/null @@ -1,81 +0,0 @@ ---- - src/Makefile.in | 2 +- - src/fips.c | 39 ++++++++++++++++++++++++++++++++------- - 2 files changed, 33 insertions(+), 8 deletions(-) - -Index: libgcrypt-1.9.0/src/fips.c -=================================================================== ---- libgcrypt-1.9.0.orig/src/fips.c -+++ libgcrypt-1.9.0/src/fips.c -@@ -603,23 +603,49 @@ run_random_selftests (void) - return !!err; - } - -+#ifdef ENABLE_HMAC_BINARY_CHECK -+static int -+get_library_path(const char *libname, const char *symbolname, char *path, size_t pathlen) -+{ -+ Dl_info info; -+ void *dl, *sym; -+ int rv = -1; -+ -+ dl = dlopen(libname, RTLD_LAZY); -+ if (dl == NULL) -+ return -1; -+ -+ sym = dlsym(dl, symbolname); -+ if (sym != NULL && dladdr(sym, &info)) -+ { -+ strncpy(path, info.dli_fname, pathlen-1); -+ path[pathlen-1] = '\0'; -+ rv = 0; -+ } -+ -+ dlclose(dl); -+ -+ return rv; -+} -+#endif -+ - /* Run an integrity check on the binary. Returns 0 on success. */ - static int - check_binary_integrity (void) - { - #ifdef ENABLE_HMAC_BINARY_CHECK - gpg_error_t err; -- Dl_info info; -+ char libpath[4096]; - unsigned char digest[32]; - int dlen; - char *fname = NULL; -- const char key[] = "What am I, a doctor or a moonshuttle conductor?"; -+ const char key[] = "orboDeJITITejsirpADONivirpUkvarP"; - -- if (!dladdr ("gcry_check_version", &info)) -+ if (get_library_path ("libgcrypt.so.20", "gcry_check_version", libpath, sizeof(libpath))) - err = gpg_error_from_syserror (); - else - { -- dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname, -+ dlen = _gcry_hmac256_file (digest, sizeof digest, libpath, - key, strlen (key)); - if (dlen < 0) - err = gpg_error_from_syserror (); -@@ -627,7 +652,7 @@ check_binary_integrity (void) - err = gpg_error (GPG_ERR_INTERNAL); - else - { -- fname = xtrymalloc (strlen (info.dli_fname) + 1 + 5 + 1 ); -+ fname = xtrymalloc (strlen (libpath) + 1 + 5 + 1 ); - if (!fname) - err = gpg_error_from_syserror (); - else -@@ -636,7 +661,7 @@ check_binary_integrity (void) - char *p; - - /* Prefix the basename with a dot. */ -- strcpy (fname, info.dli_fname); -+ strcpy (fname, libpath); - p = strrchr (fname, '/'); - if (p) - p++; diff --git a/libgcrypt-1.8.3-fips-ctor.patch b/libgcrypt-1.8.3-fips-ctor.patch deleted file mode 100644 index d562fc1..0000000 --- a/libgcrypt-1.8.3-fips-ctor.patch +++ /dev/null @@ -1,266 +0,0 @@ -Index: libgcrypt-1.9.0/cipher/md.c -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/md.c -+++ libgcrypt-1.9.0/cipher/md.c -@@ -564,11 +564,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; - } - } -Index: libgcrypt-1.9.0/src/fips.c -=================================================================== ---- libgcrypt-1.9.0.orig/src/fips.c -+++ libgcrypt-1.9.0/src/fips.c -@@ -90,7 +90,31 @@ static void fips_new_state (enum module_ - #define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p)) - - -- -+/* Initialize the FSM lock - this function may only -+ be called once and is intended to be run from the library -+ constructor */ -+void -+_gcry_initialize_fsm_lock (void) -+{ -+ gpg_error_t err; -+ /* Intitialize the lock to protect the FSM. */ -+ err = gpgrt_lock_init (&fsm_lock); -+ if (err) -+ { -+ /* If that fails we can't do anything but abort the -+ process. We need to use log_info so that the FSM won't -+ get involved. */ -+ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", -+ gpg_strerror (err)); -+#ifdef HAVE_SYSLOG -+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " -+ "creating FSM lock failed: %s - abort", -+ gpg_strerror (err)); -+#endif /*HAVE_SYSLOG*/ -+ abort (); -+ } -+} -+ - /* Check whether the OS is in FIPS mode and record that in a module - local variable. If FORCE is passed as true, fips mode will be - enabled anyway. Note: This function is not thread-safe and should -@@ -100,7 +124,6 @@ void - _gcry_initialize_fips_mode (int force) - { - static int done; -- gpg_error_t err; - - /* Make sure we are not accidentally called twice. */ - if (done) -@@ -190,24 +213,6 @@ _gcry_initialize_fips_mode (int force) - /* Yes, we are in FIPS mode. */ - FILE *fp; - -- /* Intitialize the lock to protect the FSM. */ -- err = gpgrt_lock_init (&fsm_lock); -- if (err) -- { -- /* If that fails we can't do anything but abort the -- process. We need to use log_info so that the FSM won't -- get involved. */ -- log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", -- gpg_strerror (err)); --#ifdef HAVE_SYSLOG -- syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " -- "creating FSM lock failed: %s - abort", -- gpg_strerror (err)); --#endif /*HAVE_SYSLOG*/ -- abort (); -- } -- -- - /* If the FIPS force files exists, is readable and has a number - != 0 on its first line, we enable the enforced fips mode. */ - fp = fopen (FIPS_FORCE_FILE, "r"); -@@ -356,16 +361,20 @@ _gcry_fips_is_operational (void) - { - int result; - -- if (!fips_mode ()) -+ lock_fsm (); -+ if (current_state == STATE_POWERON && !fips_mode ()) -+ /* If we are at this point in POWERON state it means the FIPS -+ module installation was not completed. (/etc/system-fips -+ is not present.) */ - result = 1; - else - { -- lock_fsm (); -- if (current_state == STATE_INIT) -+ if (current_state == STATE_INIT || current_state == STATE_SELFTEST) - { -- /* If we are still in the INIT state, we need to run the -- selftests so that the FSM can eventually get into -- operational state. Given that we would need a 2-phase -+ /* If we are still in the INIT (or SELFTEST) state, -+ we need to run (or finish) the selftests so -+ that the FSM can eventually get into operational -+ state. Given that we would need a 2-phase - initialization of libgcrypt, but that has traditionally - not been enforced, we use this on demand self-test - checking. Note that Proper applications would do the -@@ -381,9 +390,11 @@ _gcry_fips_is_operational (void) - lock_fsm (); - } - -- result = (current_state == STATE_OPERATIONAL); -- unlock_fsm (); -+ result = (current_state == STATE_OPERATIONAL) || !fips_mode (); -+ /* We always run the selftests but ignore the result -+ in non-FIPS mode. */ - } -+ unlock_fsm (); - return result; - } - -@@ -729,9 +740,25 @@ _gcry_fips_run_selftests (int extended) - { - enum module_states result = STATE_ERROR; - gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED; -+ int in_poweron; - -- if (fips_mode ()) -- fips_new_state (STATE_SELFTEST); -+ lock_fsm (); -+ in_poweron = (current_state == STATE_POWERON); -+ unlock_fsm (); -+ -+ fips_new_state (STATE_SELFTEST); -+ -+ /* We first check the integrity of the binary. -+ If run from the constructor we are in POWERON state, -+ we return and finish the remaining selftests before -+ real use of the library. It will be in the POWERON -+ state meanwhile. */ -+ if (in_poweron) -+ if (check_binary_integrity ()) -+ goto leave; -+ -+ if (in_poweron) -+ return 0; - - if (run_cipher_selftests (extended)) - goto leave; -@@ -753,21 +780,12 @@ _gcry_fips_run_selftests (int extended) - if (run_pubkey_selftests (extended)) - goto leave; - -- if (fips_mode ()) -- { -- /* Now check the integrity of the binary. We do this this after -- having checked the HMAC code. */ -- if (check_binary_integrity ()) -- goto leave; -- } -- - /* All selftests passed. */ - result = STATE_OPERATIONAL; - ec = 0; - - leave: -- if (fips_mode ()) -- fips_new_state (result); -+ fips_new_state (result); - - return ec; - } -@@ -823,6 +841,7 @@ fips_new_state (enum module_states new_s - { - case STATE_POWERON: - if (new_state == STATE_INIT -+ || new_state == STATE_SELFTEST - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; -@@ -837,6 +856,8 @@ fips_new_state (enum module_states new_s - - case STATE_SELFTEST: - if (new_state == STATE_OPERATIONAL -+ || new_state == STATE_INIT -+ || new_state == STATE_SELFTEST - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; -Index: libgcrypt-1.9.0/src/global.c -=================================================================== ---- libgcrypt-1.9.0.orig/src/global.c -+++ libgcrypt-1.9.0/src/global.c -@@ -141,6 +141,29 @@ global_init (void) - } - - -+#ifndef FIPS_MODULE_PATH -+#define FIPS_MODULE_PATH "/etc/system-fips" -+#endif -+ -+void __attribute__ ((constructor)) _gcry_global_constructor (void) -+{ -+ int rv; -+ -+ /* We always need the FSM lock to be functional. */ -+ _gcry_initialize_fsm_lock (); -+ -+ rv = access (FIPS_MODULE_PATH, F_OK); -+ if (rv < 0 && errno != ENOENT) -+ rv = 0; -+ -+ if (!rv) -+ { -+ /* We run the integrity check at this point. The remaining -+ selftests are run before use of the library by application. */ -+ _gcry_fips_run_selftests (0); -+ } -+} -+ - /* 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 -@@ -672,9 +695,8 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - - case GCRYCTL_FIPS_MODE_P: - if (fips_mode () -- && !_gcry_is_fips_mode_inactive () -- && !no_secure_memory) -- rc = GPG_ERR_GENERAL; /* Used as TRUE value */ -+ && !_gcry_is_fips_mode_inactive ()) -+ rc = GPG_ERR_GENERAL; /* Used as TRUE value */ - break; - - case GCRYCTL_FORCE_FIPS_MODE: -@@ -750,9 +772,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - break; - - case GCRYCTL_SET_ENFORCED_FIPS_FLAG: -- if (!_gcry_global_any_init_done) -+ if (fips_mode()) - { -- /* Not yet initialized at all. Set the enforced fips mode flag */ -+ /* We are in FIPS mode, we can set the enforced fips mode flag. */ - _gcry_set_preferred_rng_type (0); - _gcry_set_enforced_fips_mode (); - } -Index: libgcrypt-1.9.0/src/g10lib.h -=================================================================== ---- libgcrypt-1.9.0.orig/src/g10lib.h -+++ libgcrypt-1.9.0/src/g10lib.h -@@ -429,6 +429,8 @@ gpg_err_code_t _gcry_sexp_vextract_param - - extern int _gcry_no_fips_mode_required; - -+void _gcry_initialize_fsm_lock (void); -+ - void _gcry_initialize_fips_mode (int force); - - /* This macro returns true if fips mode is enabled. This is diff --git a/libgcrypt-1.8.4-fips-keygen.patch b/libgcrypt-1.8.4-fips-keygen.patch deleted file mode 100644 index e4b40f6..0000000 --- a/libgcrypt-1.8.4-fips-keygen.patch +++ /dev/null @@ -1,66 +0,0 @@ -Index: libgcrypt-1.9.1/cipher/dsa.c -=================================================================== ---- libgcrypt-1.9.1.orig/cipher/dsa.c -+++ libgcrypt-1.9.1/cipher/dsa.c -@@ -457,13 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen); -- else -+ 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; -@@ -859,13 +868,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; - } - -Index: libgcrypt-1.9.1/cipher/rsa.c -=================================================================== ---- libgcrypt-1.9.1.orig/cipher/rsa.c -+++ libgcrypt-1.9.1/cipher/rsa.c -@@ -389,7 +389,7 @@ generate_fips (RSA_secret_key *sk, unsig - - if (nbits < 1024 || (nbits & 0x1FF)) - return GPG_ERR_INV_VALUE; -- if (_gcry_enforced_fips_mode() && nbits != 2048 && nbits != 3072) -+ if (fips_mode() && nbits < 2048) - return GPG_ERR_INV_VALUE; - - /* The random quality depends on the transient_key flag. */ -@@ -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 --git a/libgcrypt-1.8.4-fips_ctor_skip_integrity_check.patch b/libgcrypt-1.8.4-fips_ctor_skip_integrity_check.patch deleted file mode 100644 index 36044e4..0000000 --- a/libgcrypt-1.8.4-fips_ctor_skip_integrity_check.patch +++ /dev/null @@ -1,32 +0,0 @@ -Index: libgcrypt-1.8.4/src/global.c -=================================================================== ---- libgcrypt-1.8.4.orig/src/global.c -+++ libgcrypt-1.8.4/src/global.c -@@ -141,27 +141,10 @@ global_init (void) - } - - --#ifndef FIPS_MODULE_PATH --#define FIPS_MODULE_PATH "/etc/system-fips" --#endif -- - void __attribute__ ((constructor)) _gcry_global_constructor (void) - { -- int rv; -- - /* We always need the FSM lock to be functional. */ - _gcry_initialize_fsm_lock (); -- -- rv = access (FIPS_MODULE_PATH, F_OK); -- if (rv < 0 && errno != ENOENT) -- rv = 0; -- -- if (!rv) -- { -- /* We run the integrity check at this point. The remaining -- selftests are run before use of the library by application. */ -- _gcry_fips_run_selftests (0); -- } - } - - /* This function is called by the macro fips_is_operational and makes diff --git a/libgcrypt-1.8.4-getrandom.patch b/libgcrypt-1.8.4-getrandom.patch deleted file mode 100644 index 6158b35..0000000 --- a/libgcrypt-1.8.4-getrandom.patch +++ /dev/null @@ -1,124 +0,0 @@ -Index: libgcrypt-1.9.1/random/random-csprng.c -=================================================================== ---- libgcrypt-1.9.1.orig/random/random-csprng.c -+++ libgcrypt-1.9.1/random/random-csprng.c -@@ -55,6 +55,10 @@ - #ifdef __MINGW32__ - #include - #endif -+#if defined(__linux__) && defined(HAVE_SYSCALL) -+# include -+# include -+#endif - #include "g10lib.h" - #include "random.h" - #include "rand-internal.h" -@@ -1202,6 +1206,22 @@ getfnc_gather_random (void))(void (*)(co - enum random_origins, size_t, int); - - #if USE_RNDLINUX -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ long ret; -+ char buffer[1]; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret != -1 || errno != ENOSYS) -+ { -+ fnc = _gcry_rndlinux_gather_random; -+ return fnc; -+ } -+ else -+ /* The syscall is not supported - fallback to /dev/urandom. */ -+#endif - if ( !access (NAME_OF_DEV_RANDOM, R_OK) - && !access (NAME_OF_DEV_URANDOM, R_OK)) - { -Index: libgcrypt-1.9.1/random/random.c -=================================================================== ---- libgcrypt-1.9.1.orig/random/random.c -+++ libgcrypt-1.9.1/random/random.c -@@ -110,8 +110,8 @@ _gcry_random_read_conf (void) - unsigned int result = 0; - - fp = fopen (fname, "r"); -- if (!fp) -- return result; -+ if (!fp) /* We make only_urandom the default. */ -+ return RANDOM_CONF_ONLY_URANDOM; - - for (;;) - { -Index: libgcrypt-1.9.1/random/rndlinux.c -=================================================================== ---- libgcrypt-1.9.1.orig/random/rndlinux.c -+++ libgcrypt-1.9.1/random/rndlinux.c -@@ -39,6 +39,7 @@ extern int getentropy (void *buf, size_t - #if defined(__linux__) || !defined(HAVE_GETENTROPY) - #ifdef HAVE_SYSCALL - # include -+# include - # ifdef __NR_getrandom - # define getentropy(buf,buflen) syscall (__NR_getrandom, buf, buflen, 0) - # endif -@@ -155,12 +156,12 @@ _gcry_rndlinux_gather_random (void (*add - if (!add) - { - /* Special mode to close the descriptors. */ -- if (fd_random != -1) -+ if (fd_random >= 0) - { - close (fd_random); - fd_random = -1; - } -- if (fd_urandom != -1) -+ if (fd_urandom >= 0) - { - close (fd_urandom); - fd_urandom = -1; -@@ -176,12 +177,12 @@ _gcry_rndlinux_gather_random (void (*add - apid = getpid (); - if (my_pid != apid) - { -- if (fd_random != -1) -+ if (fd_random >= 0) - { - close (fd_random); - fd_random = -1; - } -- if (fd_urandom != -1) -+ if (fd_urandom >= 0) - { - close (fd_urandom); - fd_urandom = -1; -@@ -230,6 +231,17 @@ _gcry_rndlinux_gather_random (void (*add - { - if (fd_urandom == -1) - { -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ long ret; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret > -1 || errno == EAGAIN || errno == EINTR) -+ fd_urandom = -2; -+ else /* The syscall is not supported - fallback to /dev/urandom. */ -+#endif - fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); - ever_opened |= 2; - } -@@ -272,9 +284,7 @@ _gcry_rndlinux_gather_random (void (*add - _gcry_post_syscall (); - } - while (ret == -1 && errno == EINTR); -- if (ret == -1 && errno == ENOSYS) -- ; /* getentropy is not supported - fallback to pulling from fd. */ -- else -+ if (1) - { /* getentropy is supported. Some sanity checks. */ - if (ret == -1) - log_fatal ("unexpected error from getentropy: %s\n", diff --git a/libgcrypt-1.8.4-use_xfree.patch b/libgcrypt-1.8.4-use_xfree.patch deleted file mode 100644 index b104472..0000000 --- a/libgcrypt-1.8.4-use_xfree.patch +++ /dev/null @@ -1,39 +0,0 @@ -Index: libgcrypt-1.8.4/src/hmac256.c -=================================================================== ---- libgcrypt-1.8.4.orig/src/hmac256.c -+++ libgcrypt-1.8.4/src/hmac256.c -@@ -69,6 +69,7 @@ typedef uint32_t u32; - - #ifdef STANDALONE - #define xtrymalloc(a) malloc((a)) -+#define xfree(a) free((a)) - #define gpg_err_set_errno(a) (errno = (a)) - #else - #include "g10lib.h" -@@ -341,7 +342,7 @@ _gcry_hmac256_new (const void *key, size - tmphd = _gcry_hmac256_new (NULL, 0); - if (!tmphd) - { -- free (hd); -+ xfree (hd); - return NULL; - } - _gcry_hmac256_update (tmphd, key, keylen); -@@ -373,7 +374,7 @@ _gcry_hmac256_release (hmac256_context_t - /* Note: We need to take care not to modify errno. */ - if (ctx->use_hmac) - my_wipememory (ctx->opad, 64); -- free (ctx); -+ xfree (ctx); - } - } - -@@ -489,7 +490,7 @@ _gcry_hmac256_file (void *result, size_t - while ( (nread = fread (buffer, 1, buffer_size, fp))) - _gcry_hmac256_update (hd, buffer, nread); - -- free (buffer); -+ xfree (buffer); - - if (ferror (fp)) - { diff --git a/libgcrypt-1.9.4.tar.bz2 b/libgcrypt-1.9.4.tar.bz2 deleted file mode 100644 index f9c5ce6..0000000 --- a/libgcrypt-1.9.4.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ea849c83a72454e3ed4267697e8ca03390aee972ab421e7df69dfe42b65caaf7 -size 3239704 diff --git a/libgcrypt-1.9.4.tar.bz2.sig b/libgcrypt-1.9.4.tar.bz2.sig deleted file mode 100644 index a55e817dae0e0409ada92a4f0f42a1188592709a7396cb69c1690ae31484d44c..0000000000000000000000000000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119 zcmeAuWnmEGV2~A4WXWBXm$E!p!y#PSlPRcU`VKV*t6Qv0iAtqe3|yQ7Fp;_`4F5F0 zYnXlLa_N2BT40uS_TGwZTfNmH19bVbGBvi;eO~&6;h)yzRj)przRl5cN_O( -Date: Wed, 19 Jan 2022 11:41:40 +0900 -Subject: [PATCH 2/2] fips: Reject shorter key for HMAC in FIPS mode. - -* cipher/md.c (prepare_macpads): Reject < 112-bit key. -* cipher/kdf.c (selftest_pbkdf2): Remove selftest cases with shorter -key. -* cipher/mac-hmac.c (selftests_sha224, selftests_sha256): Likewise. -(selftests_sha384, selftests_sha512, selftests_sha3): Likewise. -* tests/basic.c (check_one_hmac) Handle an error when shorter key -is rejected. -(check_one_mac): Likewise. -* tests/t-kdf.c (check_pbkdf2, check_scrypt): Likewise. - --- - -GnuPG-bug-id: 5512 -Signed-off-by: NIIBE Yutaka ---- - cipher/kdf.c | 76 ++--------------------------------------------- - cipher/mac-hmac.c | 67 ----------------------------------------- - cipher/md.c | 3 ++ - tests/basic.c | 29 +++++++++++++++--- - tests/t-kdf.c | 38 ++++++++++++++++++++---- - 5 files changed, 62 insertions(+), 151 deletions(-) - -Index: libgcrypt-1.9.4/cipher/kdf.c -=================================================================== ---- libgcrypt-1.9.4.orig/cipher/kdf.c -+++ libgcrypt-1.9.4/cipher/kdf.c -@@ -324,6 +324,10 @@ check_one (int algo, int hash_algo, - unsigned char key[512]; /* hardcoded to avoid allocation */ - size_t keysize = expectlen; - -+ /* Skip test with shoter passphrase in FIPS mode. */ -+ if (fips_mode () && passphraselen < 14) -+ return NULL; -+ - if (keysize > sizeof(key)) - return "invalid tests data"; - -Index: libgcrypt-1.9.4/cipher/mac-hmac.c -=================================================================== ---- libgcrypt-1.9.4.orig/cipher/mac-hmac.c -+++ libgcrypt-1.9.4/cipher/mac-hmac.c -@@ -241,6 +241,11 @@ check_one (int algo, - const unsigned char *digest; - - /* printf ("HMAC algo %d\n", algo); */ -+ -+ /* Skip test with shoter key in FIPS mode. */ -+ if (fips_mode () && keylen < 14) -+ return NULL; -+ - if (trunc) - { - if (_gcry_md_get_algo_dlen (algo) < expectlen) -Index: libgcrypt-1.9.4/cipher/md.c -=================================================================== ---- libgcrypt-1.9.4.orig/cipher/md.c -+++ libgcrypt-1.9.4/cipher/md.c -@@ -903,6 +903,9 @@ prepare_macpads (gcry_md_hd_t a, const u - { - GcryDigestEntry *r; - -+ if (fips_mode () && keylen < 14) -+ return GPG_ERR_INV_VALUE; -+ - if (!a->ctx->list) - return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled. */ - -Index: libgcrypt-1.9.4/tests/basic.c -=================================================================== ---- libgcrypt-1.9.4.orig/tests/basic.c -+++ libgcrypt-1.9.4/tests/basic.c -@@ -12016,7 +12016,19 @@ check_one_hmac (int algo, const char *da - return; - } - -- gcry_md_setkey( hd, key, keylen ); -+ err = gcry_md_setkey( hd, key, keylen ); -+ if (err) -+ { -+ if (in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, -+ " shorter key (%d) rejected correctly in fips mode\n", -+ keylen); -+ } -+ gcry_md_close (hd); -+ return; -+ } - - gcry_md_write (hd, data, datalen); - -@@ -12420,9 +12432,18 @@ check_one_mac (int algo, const char *dat - clutter_vector_registers(); - err = gcry_mac_setkey (hd, key, keylen); - if (err) -- fail("algo %d, mac gcry_mac_setkey failed: %s\n", algo, gpg_strerror (err)); -- if (err) -- goto out; -+ { -+ if (in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, -+ " shorter key (%d) rejected correctly in fips mode\n", -+ keylen); -+ } -+ else -+ fail("algo %d, mac gcry_mac_setkey failed: %s\n", algo, gpg_strerror (err)); -+ goto out; -+ } - - if (ivlen && iv) - { -Index: libgcrypt-1.9.4/tests/t-kdf.c -=================================================================== ---- libgcrypt-1.9.4.orig/tests/t-kdf.c -+++ libgcrypt-1.9.4/tests/t-kdf.c -@@ -31,6 +31,8 @@ - #define PGM "t-kdf" - #include "t-common.h" - -+static int in_fips_mode; -+ - - static void - dummy_consumer (volatile char *buffer, size_t buflen) -@@ -858,8 +860,7 @@ check_openpgp (void) - if (tv[tvidx].disabled) - continue; - /* MD5 isn't supported in fips mode */ -- if (gcry_fips_mode_active() -- && tv[tvidx].hashalgo == GCRY_MD_MD5) -+ if (in_fips_mode && tv[tvidx].hashalgo == GCRY_MD_MD5) - continue; - if (verbose) - fprintf (stderr, "checking S2K test vector %d\n", tvidx); -@@ -1104,7 +1105,7 @@ check_pbkdf2 (void) - GCRY_KDF_PBKDF2, tv[tvidx].hashalgo, - tv[tvidx].salt, tv[tvidx].saltlen, - tv[tvidx].c, tv[tvidx].dklen, outbuf); -- if (gcry_fips_mode_active() && tvidx > 6) -+ if (in_fips_mode && tvidx > 6) - { - if (!err) - fail ("pbkdf2 test %d unexpectedly passed in FIPS mode: %s\n", -@@ -1112,7 +1113,17 @@ check_pbkdf2 (void) - continue; - } - if (err) -- fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err)); -+ { -+ if (in_fips_mode && tv[tvidx].plen < 14) -+ { -+ if (verbose) -+ fprintf (stderr, -+ " shorter key (%u) rejected correctly in fips mode\n", -+ (unsigned int)tv[tvidx].plen); -+ } -+ else -+ fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err)); -+ } - else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) - { - fail ("pbkdf2 test %d failed: mismatch\n", tvidx); -@@ -1209,7 +1220,17 @@ check_scrypt (void) - tv[tvidx].salt, tv[tvidx].saltlen, - tv[tvidx].parm_p, tv[tvidx].dklen, outbuf); - if (err) -- fail ("scrypt test %d failed: %s\n", tvidx, gpg_strerror (err)); -+ { -+ if (in_fips_mode && tv[tvidx].plen < 14) -+ { -+ if (verbose) -+ fprintf (stderr, -+ " shorter key (%u) rejected correctly in fips mode\n", -+ (unsigned int)tv[tvidx].plen); -+ } -+ else -+ fail ("scrypt test %d failed: %s\n", tvidx, gpg_strerror (err)); -+ } - else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) - { - fail ("scrypt test %d failed: mismatch\n", tvidx); -@@ -1281,7 +1302,12 @@ main (int argc, char **argv) - if (!gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - -- xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ -+ if (!in_fips_mode) -+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); -+ - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); diff --git a/libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch b/libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch deleted file mode 100644 index 0356bf2..0000000 --- a/libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch +++ /dev/null @@ -1,245 +0,0 @@ -Index: libgcrypt-1.9.0/cipher/pubkey.c -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/pubkey.c -+++ libgcrypt-1.9.0/cipher/pubkey.c -@@ -384,6 +384,33 @@ _gcry_pk_decrypt (gcry_sexp_t *r_plain, - } - - -+static gcry_err_code_t -+calculate_hash (gcry_md_hd_t hd, gcry_sexp_t* s_hash) -+{ -+ gcry_err_code_t rc; -+ const unsigned char *digest; -+ int algo; -+ -+ if (!hd) -+ return 0; -+ -+ rc = _gcry_pk_util_get_algo (*s_hash, &algo); -+ if (rc) -+ return rc; -+ -+ digest = _gcry_md_read(hd, algo); -+ if (!digest) -+ return GPG_ERR_DIGEST_ALGO; -+ -+ rc = _gcry_sexp_build (s_hash, NULL, -+ "(data (flags pkcs1)(hash %s %b))", -+ _gcry_md_algo_name(algo), -+ (int) _gcry_md_get_algo_dlen(algo), -+ digest); -+ -+ return rc; -+} -+ - - /* - Create a signature. -@@ -414,7 +441,8 @@ _gcry_pk_decrypt (gcry_sexp_t *r_plain, - Note that (hash algo) in R_SIG is not used. - */ - gcry_err_code_t --_gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey) -+_gcry_pk_sign_md (gcry_sexp_t *r_sig, gcry_md_hd_t hd, gcry_sexp_t s_hash, -+ gcry_sexp_t s_skey) - { - gcry_err_code_t rc; - gcry_pk_spec_t *spec; -@@ -426,6 +454,10 @@ _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_ - if (rc) - goto leave; - -+ rc = calculate_hash (hd, &s_hash); -+ if (rc) -+ goto leave; -+ - if (spec->sign) - rc = spec->sign (r_sig, s_hash, keyparms); - else -@@ -437,6 +469,13 @@ _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_ - } - - -+gcry_err_code_t -+_gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey) -+{ -+ return _gcry_pk_sign_md (r_sig, NULL, s_hash, s_skey); -+} -+ -+ - /* - Verify a signature. - -@@ -445,7 +484,8 @@ _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_ - as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data - must be an S-Exp like the one in sign too. */ - gcry_err_code_t --_gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey) -+_gcry_pk_verify_md (gcry_sexp_t s_sig, gcry_md_hd_t hd, gcry_sexp_t s_hash, -+ gcry_sexp_t s_pkey) - { - gcry_err_code_t rc; - gcry_pk_spec_t *spec; -@@ -455,6 +495,10 @@ _gcry_pk_verify (gcry_sexp_t s_sig, gcry - if (rc) - goto leave; - -+ rc = calculate_hash (hd, &s_hash); -+ if (rc) -+ goto leave; -+ - if (spec->verify) - rc = spec->verify (s_sig, s_hash, keyparms); - else -@@ -466,6 +510,13 @@ _gcry_pk_verify (gcry_sexp_t s_sig, gcry - } - - -+gcry_err_code_t -+_gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey) -+{ -+ return _gcry_pk_verify_md (s_sig, NULL, s_hash, s_pkey); -+} -+ -+ - /* - Test a key. - -Index: libgcrypt-1.9.0/cipher/pubkey-internal.h -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/pubkey-internal.h -+++ libgcrypt-1.9.0/cipher/pubkey-internal.h -@@ -43,6 +43,8 @@ void _gcry_pk_util_free_encoding_ctx (st - gcry_err_code_t _gcry_pk_util_data_to_mpi (gcry_sexp_t input, - gcry_mpi_t *ret_mpi, - struct pk_encoding_ctx *ctx); -+gcry_err_code_t _gcry_pk_util_get_algo (gcry_sexp_t input, -+ int *algo); - - - -Index: libgcrypt-1.9.0/cipher/pubkey-util.c -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/pubkey-util.c -+++ libgcrypt-1.9.0/cipher/pubkey-util.c -@@ -1158,3 +1158,50 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t i - - return rc; - } -+ -+ -+gcry_err_code_t -+_gcry_pk_util_get_algo (gcry_sexp_t input, int *algo) -+{ -+ gcry_err_code_t rc = 0; -+ gcry_sexp_t ldata, list = NULL; -+ const char *s; -+ size_t n; -+ int lalgo; -+ -+ ldata = sexp_find_token (input, "data", 0); -+ if (!ldata) -+ { -+ rc = GPG_ERR_INV_OBJ; -+ goto leave; -+ } -+ -+ list = sexp_find_token (ldata, "hash-algo", 0); -+ if (!list) -+ { -+ rc = GPG_ERR_INV_OBJ; -+ goto leave; -+ } -+ -+ s = sexp_nth_data (list, 1, &n); -+ if (!s) -+ { -+ rc = GPG_ERR_NO_OBJ; -+ goto leave; -+ } -+ -+ lalgo = get_hash_algo (s, n); -+ if (!lalgo) -+ { -+ rc = GPG_ERR_DIGEST_ALGO; -+ goto leave; -+ } -+ -+ *algo = lalgo; -+ -+ leave: -+ sexp_release (ldata); -+ sexp_release (list); -+ -+ return rc; -+} -Index: libgcrypt-1.9.0/src/g10lib.h -=================================================================== ---- libgcrypt-1.9.0.orig/src/g10lib.h -+++ libgcrypt-1.9.0/src/g10lib.h -@@ -299,6 +299,10 @@ gpg_err_code_t _gcry_generate_fips186_3_ - gpg_err_code_t _gcry_fips186_4_prime_check (const gcry_mpi_t x, - unsigned int bits); - -+gcry_err_code_t _gcry_pk_sign_md (gcry_sexp_t *r_sig, gcry_md_hd_t hd, -+ gcry_sexp_t s_hash, gcry_sexp_t s_skey); -+gcry_err_code_t _gcry_pk_verify_md (gcry_sexp_t s_sig, gcry_md_hd_t hd, -+ gcry_sexp_t s_hash, gcry_sexp_t s_pkey); - - /* Replacements of missing functions (missing-string.c). */ - #ifndef HAVE_STPCPY -Index: libgcrypt-1.9.0/src/visibility.c -=================================================================== ---- libgcrypt-1.9.0.orig/src/visibility.c -+++ libgcrypt-1.9.0/src/visibility.c -@@ -992,6 +992,18 @@ gcry_pk_decrypt (gcry_sexp_t *result, gc - } - - gcry_error_t -+gcry_pk_sign_md (gcry_sexp_t *result, gcry_md_hd_t hd, gcry_sexp_t data, -+ gcry_sexp_t skey) -+{ -+ if (!fips_is_operational ()) -+ { -+ *result = NULL; -+ return gpg_error (fips_not_operational ()); -+ } -+ return gpg_error (_gcry_pk_sign_md (result, hd, data, skey)); -+} -+ -+gcry_error_t - gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey) - { - if (!fips_is_operational ()) -@@ -1003,6 +1015,15 @@ gcry_pk_sign (gcry_sexp_t *result, gcry_ - } - - gcry_error_t -+gcry_pk_verify_md (gcry_sexp_t sigval, gcry_md_hd_t hd, gcry_sexp_t data, -+ gcry_sexp_t pkey) -+{ -+ if (!fips_is_operational ()) -+ return gpg_error (fips_not_operational ()); -+ return gpg_error (_gcry_pk_verify_md (sigval, hd, data, pkey)); -+} -+ -+gcry_error_t - gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey) - { - if (!fips_is_operational ()) -Index: libgcrypt-1.9.0/src/visibility.h -=================================================================== ---- libgcrypt-1.9.0.orig/src/visibility.h -+++ libgcrypt-1.9.0/src/visibility.h -@@ -360,8 +360,10 @@ MARK_VISIBLEX (_gcry_mpi_get_const) - #define gcry_pk_get_param _gcry_USE_THE_UNDERSCORED_FUNCTION - #define gcry_pk_get_nbits _gcry_USE_THE_UNDERSCORED_FUNCTION - #define gcry_pk_map_name _gcry_USE_THE_UNDERSCORED_FUNCTION -+#define gcry_pk_sign_md _gcry_USE_THE_UNDERSCORED_FUNCTION - #define gcry_pk_sign _gcry_USE_THE_UNDERSCORED_FUNCTION - #define gcry_pk_testkey _gcry_USE_THE_UNDERSCORED_FUNCTION -+#define gcry_pk_verify_md _gcry_USE_THE_UNDERSCORED_FUNCTION - #define gcry_pk_verify _gcry_USE_THE_UNDERSCORED_FUNCTION - #define gcry_pubkey_get_sexp _gcry_USE_THE_UNDERSCORED_FUNCTION - #define gcry_ecc_get_algo_keylen _gcry_USE_THE_UNDERSCORED_FUNCTION diff --git a/libgcrypt-FIPS-RSA-keylen-tests.patch b/libgcrypt-FIPS-RSA-keylen-tests.patch deleted file mode 100644 index 4cba8d3..0000000 --- a/libgcrypt-FIPS-RSA-keylen-tests.patch +++ /dev/null @@ -1,585 +0,0 @@ -From cc3571a1f2244bdf829d7d16dd546131711eb8a9 Mon Sep 17 00:00:00 2001 -From: NIIBE Yutaka -Date: Mon, 8 Nov 2021 13:57:18 +0900 -Subject: tests: Expect errors from algorithms not supported in - FIPS mode. - -* tests/basic.c (FLAG_NOFIPS): New. -(check_pubkey_sign): Pass and handle NOFIPS flag. -(check_pubkey_sign_ecdsa): Likewise. -(check_pubkey_crypt): Likewise. -(do_check_one_pubkey): Pass flags. -(check_pubkey): Mark explicitly algorithms expected not to work in -FIPS mode and make sure they fail. - --- - -Co-authored-by: NIIBE Yutaka -Signed-off-by: Jakub Jelen ---- - tests/basic.c | 65 ++++++++++++++++++++++++++++++++++++--------------- - 1 file changed, 46 insertions(+), 19 deletions(-) - -Index: libgcrypt-1.9.4/tests/basic.c -=================================================================== ---- libgcrypt-1.9.4.orig/tests/basic.c -+++ libgcrypt-1.9.4/tests/basic.c -@@ -55,9 +55,10 @@ typedef struct test_spec_pubkey - } - test_spec_pubkey_t; - --#define FLAG_CRYPT (1 << 0) --#define FLAG_SIGN (1 << 1) --#define FLAG_GRIP (1 << 2) -+#define FLAG_CRYPT (1 << 0) -+#define FLAG_SIGN (1 << 1) -+#define FLAG_GRIP (1 << 2) -+#define FLAG_NOFIPS (1 << 3) - - static int in_fips_mode; - -@@ -13509,7 +13510,8 @@ verify_one_signature (gcry_sexp_t pkey, - /* Test the public key sign function using the private key SKEY. PKEY - is used for verification. */ - static void --check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) -+check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo, -+ int flags) - { - gcry_error_t rc; - gcry_sexp_t sig, badhash, hash; -@@ -13588,6 +13590,7 @@ check_pubkey_sign (int n, gcry_sexp_t sk - if (rc) - die ("converting data failed: %s\n", gpg_strerror (rc)); - -+ sig = NULL; - for (dataidx = 0; datas[dataidx].data; dataidx++) - { - if (datas[dataidx].algo && datas[dataidx].algo != algo) -@@ -13603,12 +13606,19 @@ check_pubkey_sign (int n, gcry_sexp_t sk - die ("converting data failed: %s\n", gpg_strerror (rc)); - - rc = gcry_pk_sign (&sig, hash, skey); -+ if (in_fips_mode && (flags & FLAG_NOFIPS)) -+ { -+ if (!rc) -+ fail ("gcry_pk_sign did not fail as expected in FIPS mode\n"); -+ goto next; -+ } - if (gcry_err_code (rc) != datas[dataidx].expected_rc) - fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc)); - - if (!rc) - verify_one_signature (pkey, hash, badhash, sig); - -+ next: - gcry_sexp_release (sig); - sig = NULL; - gcry_sexp_release (hash); -@@ -13622,7 +13632,8 @@ check_pubkey_sign (int n, gcry_sexp_t sk - /* Test the public key sign function using the private key SKEY. PKEY - is used for verification. This variant is only used for ECDSA. */ - static void --check_pubkey_sign_ecdsa (int n, gcry_sexp_t skey, gcry_sexp_t pkey) -+check_pubkey_sign_ecdsa (int n, gcry_sexp_t skey, gcry_sexp_t pkey, -+ int flags) - { - gcry_error_t rc; - gcry_sexp_t sig, badhash, hash; -@@ -13704,6 +13715,7 @@ check_pubkey_sign_ecdsa (int n, gcry_sex - - nbits = gcry_pk_get_nbits (skey); - -+ sig = NULL; - for (dataidx = 0; datas[dataidx].data; dataidx++) - { - if (datas[dataidx].nbits != nbits) -@@ -13723,6 +13735,12 @@ check_pubkey_sign_ecdsa (int n, gcry_sex - die ("converting data failed: %s\n", gpg_strerror (rc)); - - rc = gcry_pk_sign (&sig, hash, skey); -+ if (in_fips_mode && (flags & FLAG_NOFIPS)) -+ { -+ if (!rc) -+ fail ("gcry_pk_sign did not fail as expected in FIPS mode\n"); -+ goto next; -+ } - if (gcry_err_code (rc) != datas[dataidx].expected_rc) - fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc)); - -@@ -13732,6 +13750,7 @@ check_pubkey_sign_ecdsa (int n, gcry_sex - if (!rc) - verify_one_signature (pkey, hash, badhash, sig); - -+ next: - gcry_sexp_release (sig); - sig = NULL; - gcry_sexp_release (badhash); -@@ -13743,7 +13762,8 @@ check_pubkey_sign_ecdsa (int n, gcry_sex - - - static void --check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) -+check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo, -+ int flags) - { - gcry_error_t rc; - gcry_sexp_t plain = NULL; -@@ -13876,6 +13896,12 @@ check_pubkey_crypt (int n, gcry_sexp_t s - die ("converting data failed: %s\n", gpg_strerror (rc)); - - rc = gcry_pk_encrypt (&ciph, data, pkey); -+ if (in_fips_mode && (flags & FLAG_NOFIPS)) -+ { -+ if (!rc) -+ fail ("gcry_pk_encrypt did not fail as expected in FIPS mode\n"); -+ goto next; -+ } - if (gcry_err_code (rc) != datas[dataidx].encrypt_expected_rc) - fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (rc)); - -@@ -13974,6 +14000,7 @@ check_pubkey_crypt (int n, gcry_sexp_t s - } - } - -+ next: - gcry_sexp_release (plain); - plain = NULL; - gcry_sexp_release (ciph); -@@ -14005,17 +14032,17 @@ static void - do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey, - const unsigned char *grip, int algo, int flags) - { -- if (flags & FLAG_SIGN) -+ if ((flags & FLAG_SIGN)) - { - if (algo == GCRY_PK_ECDSA) -- check_pubkey_sign_ecdsa (n, skey, pkey); -+ check_pubkey_sign_ecdsa (n, skey, pkey, flags); - else -- check_pubkey_sign (n, skey, pkey, algo); -+ check_pubkey_sign (n, skey, pkey, algo, flags); - } -- if (flags & FLAG_CRYPT) -- check_pubkey_crypt (n, skey, pkey, algo); -- if (grip && (flags & FLAG_GRIP)) -- check_pubkey_grip (n, grip, skey, pkey, algo); -+ if ((flags & FLAG_CRYPT)) -+ check_pubkey_crypt (n, skey, pkey, algo, flags); -+ if (grip && (flags & FLAG_GRIP)) -+ check_pubkey_grip (n, grip, skey, pkey, algo); - } - - static void -@@ -14089,7 +14116,7 @@ check_pubkey (void) - { - static const test_spec_pubkey_t pubkeys[] = { - { -- GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN | FLAG_GRIP, -+ GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN | FLAG_GRIP | FLAG_NOFIPS, /* 1k RSA */ - { - "(private-key\n" - " (rsa\n" -@@ -14228,7 +14255,7 @@ check_pubkey (void) - "\x47\xdd\x69\x55\xdb\x3a\xac\x89\x6e\x40"} - }, - { -- GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT | FLAG_GRIP, -+ GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT | FLAG_GRIP | FLAG_NOFIPS, - { - "(private-key\n" - " (ELG\n" -@@ -14360,7 +14387,7 @@ check_pubkey (void) - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } - }, - { /* GOST R 34.10-2001/2012 test 256 bit. */ -- GCRY_PK_ECDSA, FLAG_SIGN, -+ GCRY_PK_ECDSA, FLAG_SIGN | FLAG_NOFIPS, - { - "(private-key\n" - " (ecc\n" -@@ -14382,7 +14409,7 @@ check_pubkey (void) - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } - }, - { /* GOST R 34.10-2012 test 512 bit. */ -- GCRY_PK_ECDSA, FLAG_SIGN, -+ GCRY_PK_ECDSA, FLAG_SIGN | FLAG_NOFIPS, - { - "(private-key\n" - " (ecc\n" -@@ -14433,7 +14460,7 @@ check_pubkey (void) - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } - }, - { /* sm2 test */ -- GCRY_PK_ECDSA, FLAG_SIGN, -+ GCRY_PK_ECDSA, FLAG_SIGN | FLAG_NOFIPS, - { - "(private-key\n" - " (ecc\n" -From 66119e0c1a024f7cf059393c3db827eb338339b0 Mon Sep 17 00:00:00 2001 -From: NIIBE Yutaka -Date: Thu, 11 Nov 2021 13:03:58 +0900 -Subject: tests:pubkey: Replace RSA key to one of 2k. - -* tests/pubkey.c (sample_private_key_1): Use 2k key from basic.c. -(sample_private_key_1_1): Likewise. -(sample_private_key_1_2): Likewise. - --- - -GnuPG-bug-id: 5512 -Signed-off-by: NIIBE Yutaka ---- - tests/pubkey.c | 126 ++++++++++++++++++++++++++++++++++--------------- - 1 file changed, 88 insertions(+), 38 deletions(-) - -diff --git a/tests/pubkey.c b/tests/pubkey.c -index 8a482dc3..51ef0f51 100644 ---- a/tests/pubkey.c -+++ b/tests/pubkey.c -@@ -36,21 +36,40 @@ static int in_fips_mode; - static const char sample_private_key_1[] = - "(private-key\n" - " (openpgp-rsa\n" --" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" -- "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" -- "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" -- "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" -+" (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" -+" 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" -+" 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" -+" 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" -+" DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" -+" 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" -+" 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" -+" 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6" -+" CB#)\n" - " (e #010001#)\n" --" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" -- "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" -- "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" -- "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" --" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" -- "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n" --" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" -- "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n" --" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" -- "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n" -+" (d #07EF82500C403899934FE993AC5A36F14FF2DF38CF1EF315F205EE4C83EDAA19" -+" 8890FC23DE9AA933CAFB37B6A8A8DBA675411958337287310D3FF2F1DDC0CB93" -+" 7E70F57F75F833C021852B631D2B9A520E4431A03C5C3FCB5742DCD841D9FB12" -+" 771AA1620DCEC3F1583426066ED9DC3F7028C5B59202C88FDF20396E2FA0EC4F" -+" 5A22D9008F3043673931BC14A5046D6327398327900867E39CC61B2D1AFE2F48" -+" EC8E1E3861C68D257D7425F4E6F99ABD77D61F10CA100EFC14389071831B33DD" -+" 69CC8EABEF860D1DC2AAA84ABEAE5DFC91BC124DAF0F4C8EF5BBEA436751DE84" -+" 3A8063E827A024466F44C28614F93B0732A100D4A0D86D532FE1E22C7725E401" -+" #)\n" -+" (p #00C29D438F115825779631CD665A5739367F3E128ADC29766483A46CA80897E0" -+" 79B32881860B8F9A6A04C2614A904F6F2578DAE13EA67CD60AE3D0AA00A1FF9B" -+" 441485E44B2DC3D0B60260FBFE073B5AC72FAF67964DE15C8212C389D20DB9CF" -+" 54AF6AEF5C4196EAA56495DD30CF709F499D5AB30CA35E086C2A1589D6283F17" -+" 83#)\n" -+" (q #00D1984135231CB243FE959C0CBEF551EDD986AD7BEDF71EDF447BE3DA27AF46" -+" 79C974A6FA69E4D52FE796650623DE70622862713932AA2FD9F2EC856EAEAA77" -+" 88B4EA6084DC81C902F014829B18EA8B2666EC41586818E0589E18876065F97E" -+" 8D22CE2DA53A05951EC132DCEF41E70A9C35F4ACC268FFAC2ADF54FA1DA110B9" -+" 19#)\n" -+" (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04" -+" 479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4" -+" A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9" -+" AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7" -+" #)\n" - " )\n" - ")\n"; - -@@ -58,15 +77,25 @@ static const char sample_private_key_1[] = - static const char sample_private_key_1_1[] = - "(private-key\n" - " (openpgp-rsa\n" --" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" -- "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" -- "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" -- "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" -+" (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" -+" 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" -+" 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" -+" 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" -+" DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" -+" 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" -+" 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" -+" 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6" -+" CB#)\n" - " (e #010001#)\n" --" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" -- "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" -- "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" -- "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" -+" (d #07EF82500C403899934FE993AC5A36F14FF2DF38CF1EF315F205EE4C83EDAA19" -+" 8890FC23DE9AA933CAFB37B6A8A8DBA675411958337287310D3FF2F1DDC0CB93" -+" 7E70F57F75F833C021852B631D2B9A520E4431A03C5C3FCB5742DCD841D9FB12" -+" 771AA1620DCEC3F1583426066ED9DC3F7028C5B59202C88FDF20396E2FA0EC4F" -+" 5A22D9008F3043673931BC14A5046D6327398327900867E39CC61B2D1AFE2F48" -+" EC8E1E3861C68D257D7425F4E6F99ABD77D61F10CA100EFC14389071831B33DD" -+" 69CC8EABEF860D1DC2AAA84ABEAE5DFC91BC124DAF0F4C8EF5BBEA436751DE84" -+" 3A8063E827A024466F44C28614F93B0732A100D4A0D86D532FE1E22C7725E401" -+" #)\n" - " )\n" - ")\n"; - -@@ -75,29 +104,50 @@ static const char sample_private_key_1_1[] = - static const char sample_private_key_1_2[] = - "(private-key\n" - " (openpgp-rsa\n" --" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" -- "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" -- "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" -- "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" -+" (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" -+" 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" -+" 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" -+" 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" -+" DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" -+" 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" -+" 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" -+" 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6" -+" CB#)\n" - " (e #010001#)\n" --" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" -- "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" -- "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" -- "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" --" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" -- "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n" --" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" -- "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n" -+" (d #07EF82500C403899934FE993AC5A36F14FF2DF38CF1EF315F205EE4C83EDAA19" -+" 8890FC23DE9AA933CAFB37B6A8A8DBA675411958337287310D3FF2F1DDC0CB93" -+" 7E70F57F75F833C021852B631D2B9A520E4431A03C5C3FCB5742DCD841D9FB12" -+" 771AA1620DCEC3F1583426066ED9DC3F7028C5B59202C88FDF20396E2FA0EC4F" -+" 5A22D9008F3043673931BC14A5046D6327398327900867E39CC61B2D1AFE2F48" -+" EC8E1E3861C68D257D7425F4E6F99ABD77D61F10CA100EFC14389071831B33DD" -+" 69CC8EABEF860D1DC2AAA84ABEAE5DFC91BC124DAF0F4C8EF5BBEA436751DE84" -+" 3A8063E827A024466F44C28614F93B0732A100D4A0D86D532FE1E22C7725E401" -+" #)\n" -+" (p #00C29D438F115825779631CD665A5739367F3E128ADC29766483A46CA80897E0" -+" 79B32881860B8F9A6A04C2614A904F6F2578DAE13EA67CD60AE3D0AA00A1FF9B" -+" 441485E44B2DC3D0B60260FBFE073B5AC72FAF67964DE15C8212C389D20DB9CF" -+" 54AF6AEF5C4196EAA56495DD30CF709F499D5AB30CA35E086C2A1589D6283F17" -+" 83#)\n" -+" (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04" -+" 479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4" -+" A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9" -+" AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7" -+" #)\n" - " )\n" - ")\n"; - - static const char sample_public_key_1[] = - "(public-key\n" - " (rsa\n" --" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" -- "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" -- "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" -- "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" -+" (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" -+" 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" -+" 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" -+" 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" -+" DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" -+" 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" -+" 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" -+" 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6" -+" CB#)\n" - " (e #010001#)\n" - " )\n" - ")\n"; --- -2.33.1 - -From 1481607cb9db977468a75f9f4638dc1cf3ade007 Mon Sep 17 00:00:00 2001 -From: NIIBE Yutaka -Date: Thu, 11 Nov 2021 13:44:40 +0900 -Subject: tests:pkcs1v2: Skip tests with small keys in FIPS - mode. - -* tests/pkcs1v2.c (in_fips_mode): New. -(check_oaep): Skip when key size is less than 2048 in FIPS mode. -(check_pss, check_v15crypt, check_v15sign): Likewise. - --- - -GnuPG-bug-id: 5512 -Signed-off-by: NIIBE Yutaka ---- - tests/pkcs1v2.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 75 insertions(+), 3 deletions(-) - -diff --git a/tests/pkcs1v2.c b/tests/pkcs1v2.c -index 968d3fea..f26e779b 100644 ---- a/tests/pkcs1v2.c -+++ b/tests/pkcs1v2.c -@@ -36,6 +36,8 @@ - #include "t-common.h" - - -+static int in_fips_mode; -+ - static void - show_sexp (const char *prefix, gcry_sexp_t a) - { -@@ -147,6 +149,18 @@ check_oaep (void) - gcry_free (rsa_e); - gcry_free (rsa_d); - -+ if (in_fips_mode) -+ { -+ unsigned int nbits = gcry_pk_get_nbits (pub_key); -+ -+ if (nbits < 2048) -+ { -+ if (verbose > 1) -+ info ("... skipped\n"); -+ goto next; -+ } -+ } -+ - for (mno = 0; mno < DIM (tbl[0].m); mno++) - { - void *mesg, *seed, *encr; -@@ -225,6 +239,7 @@ check_oaep (void) - ciph = NULL; - } - -+ next: - gcry_sexp_release (sec_key); - gcry_sexp_release (pub_key); - } -@@ -269,6 +284,18 @@ check_pss (void) - gcry_free (rsa_e); - gcry_free (rsa_d); - -+ if (in_fips_mode) -+ { -+ unsigned int nbits = gcry_pk_get_nbits (pub_key); -+ -+ if (nbits < 2048) -+ { -+ if (verbose > 1) -+ info ("... skipped\n"); -+ goto next; -+ } -+ } -+ - for (mno = 0; mno < DIM (tbl[0].m); mno++) - { - void *mesg, *salt, *sign; -@@ -347,6 +374,7 @@ check_pss (void) - sigtmpl = NULL; - } - -+ next: - gcry_sexp_release (sec_key); - gcry_sexp_release (pub_key); - } -@@ -391,6 +419,18 @@ check_v15crypt (void) - gcry_free (rsa_e); - gcry_free (rsa_d); - -+ if (in_fips_mode) -+ { -+ unsigned int nbits = gcry_pk_get_nbits (pub_key); -+ -+ if (nbits < 2048) -+ { -+ if (verbose > 1) -+ info ("... skipped\n"); -+ goto next; -+ } -+ } -+ - for (mno = 0; mno < DIM (tbl[0].m); mno++) - { - void *mesg, *seed, *encr; -@@ -469,6 +509,7 @@ check_v15crypt (void) - ciph = NULL; - } - -+ next: - gcry_sexp_release (sec_key); - gcry_sexp_release (pub_key); - } -@@ -513,6 +554,18 @@ check_v15sign (void) - gcry_free (rsa_e); - gcry_free (rsa_d); - -+ if (in_fips_mode) -+ { -+ unsigned int nbits = gcry_pk_get_nbits (pub_key); -+ -+ if (nbits < 2048) -+ { -+ if (verbose > 1) -+ info ("... skipped\n"); -+ goto next; -+ } -+ } -+ - for (mno = 0; mno < DIM (tbl[0].m); mno++) - { - void *mesg, *sign; -@@ -583,6 +636,7 @@ check_v15sign (void) - sigtmpl = NULL; - } - -+ next: - gcry_sexp_release (sec_key); - gcry_sexp_release (pub_key); - } -@@ -597,6 +651,7 @@ main (int argc, char **argv) - int run_pss = 0; - int run_v15c = 0; - int run_v15s = 0; -+ int use_fips = 0; - - if (argc) - { argc--; argv++; } -@@ -625,6 +680,11 @@ main (int argc, char **argv) - die_on_error = 1; - argc--; argv++; - } -+ else if (!strcmp (*argv, "--fips")) -+ { -+ use_fips = 1; -+ argc--; argv++; -+ } - else if (!strcmp (*argv, "--oaep")) - { - run_oaep = 1; -@@ -651,9 +711,21 @@ main (int argc, char **argv) - run_oaep = run_pss = run_v15c = run_v15s = 1; - - xgcry_control ((GCRYCTL_SET_VERBOSITY, (int)verbose)); -- xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); -- if (!gcry_check_version ("1.5.0")) -- die ("version mismatch\n"); -+ -+ if (use_fips) -+ xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); -+ -+ /* Check that we test exactly our version - including the patchlevel. */ -+ if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL))) -+ die ("version mismatch; pgm=%s, library=%s\n", -+ GCRYPT_VERSION,gcry_check_version (NULL)); -+ -+ if ( gcry_fips_mode_active () ) -+ in_fips_mode = 1; -+ -+ if (!in_fips_mode) -+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); -+ - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); --- -2.33.1 - diff --git a/libgcrypt-FIPS-RSA-keylen.patch b/libgcrypt-FIPS-RSA-keylen.patch deleted file mode 100644 index 8417ffa..0000000 --- a/libgcrypt-FIPS-RSA-keylen.patch +++ /dev/null @@ -1,250 +0,0 @@ -From 40d63d09b2d06631f4d2c3d1b167a620d50c99f8 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 5 Nov 2021 14:19:23 +0100 -Subject: [PATCH 198/200] rsa: Check keylen constraints for key operations. - -* cipher/rsa.c (rsa_check_keysize): New. -(generate_fips): Factor out the bits check. -(rsa_encrypt): Add checking key length. -(rsa_decrypt, rsa_sign, rsa_verify): Likewise. --- - -GnuPG-bug-id: 5512 -Co-authored-by: NIIBE Yutaka -Signed-off-by: Jakub Jelen ---- - cipher/rsa.c | 58 ++++++++++++++++++++++++++++++++++++++-------------- - 1 file changed, 43 insertions(+), 15 deletions(-) - -Index: libgcrypt-1.9.4/cipher/rsa.c -=================================================================== ---- libgcrypt-1.9.4.orig/cipher/rsa.c -+++ libgcrypt-1.9.4/cipher/rsa.c -@@ -301,14 +301,6 @@ generate_std (RSA_secret_key *sk, unsign - gcry_mpi_t f; - gcry_random_level_t random_level; - -- if (fips_mode ()) -- { -- if (nbits < 1024) -- return GPG_ERR_INV_VALUE; -- if (transient_key) -- 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; - -@@ -437,6 +429,17 @@ generate_std (RSA_secret_key *sk, unsign - } - - -+/* Check the RSA key length is acceptable for key generation or usage */ -+static gpg_err_code_t -+rsa_check_keysize (unsigned int nbits) -+{ -+ if (fips_mode() && nbits < 2048) -+ return GPG_ERR_INV_VALUE; -+ -+ return GPG_ERR_NO_ERROR; -+} -+ -+ - /**************** - * Generate a key pair with a key of size NBITS. - * USE_E = 0 let Libcgrypt decide what exponent to use. -@@ -466,12 +469,15 @@ generate_fips (RSA_secret_key *sk, unsig - unsigned int pbits = nbits/2; - unsigned int i; - int pqswitch; -- gpg_err_code_t ec = GPG_ERR_NO_PRIME; -+ gpg_err_code_t ec; - - if (nbits < 1024 || (nbits & 0x1FF)) - return GPG_ERR_INV_VALUE; -- if (fips_mode() && nbits < 2048) -- return GPG_ERR_INV_VALUE; -+ ec = rsa_check_keysize (nbits); -+ if (ec) -+ return ec; -+ -+ ec = GPG_ERR_NO_PRIME; - - /* The random quality depends on the transient_key flag. */ - random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; -@@ -1360,9 +1366,13 @@ rsa_encrypt (gcry_sexp_t *r_ciph, gcry_s - gcry_mpi_t data = NULL; - RSA_public_key pk = {NULL, NULL}; - gcry_mpi_t ciph = NULL; -+ unsigned int nbits = rsa_get_nbits (keyparms); -+ -+ rc = rsa_check_keysize (nbits); -+ if (rc) -+ return rc; - -- _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, -- rsa_get_nbits (keyparms)); -+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, nbits); - - /* Extract the data. */ - rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx); -@@ -1432,9 +1442,13 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_ - gcry_mpi_t plain = NULL; - unsigned char *unpad = NULL; - size_t unpadlen = 0; -+ unsigned int nbits = rsa_get_nbits (keyparms); - -- _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, -- rsa_get_nbits (keyparms)); -+ rc = rsa_check_keysize (nbits); -+ if (rc) -+ return rc; -+ -+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, nbits); - - /* Extract the data. */ - rc = _gcry_pk_util_preparse_encval (s_data, rsa_names, &l1, &ctx); -@@ -1477,7 +1491,7 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_ - mpi_fdiv_r (data, data, sk.n); - - /* Allocate MPI for the plaintext. */ -- plain = mpi_snew (ctx.nbits); -+ plain = mpi_snew (nbits); - - /* We use blinding by default to mitigate timing attacks which can - be practically mounted over the network as shown by Brumley and -@@ -1485,7 +1499,7 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_ - if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING)) - secret (plain, data, &sk); - else -- secret_blinded (plain, data, &sk, ctx.nbits); -+ secret_blinded (plain, data, &sk, nbits); - - if (DBG_CIPHER) - log_printmpi ("rsa_decrypt res", plain); -@@ -1494,7 +1508,7 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_ - switch (ctx.encoding) - { - case PUBKEY_ENC_PKCS1: -- rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, ctx.nbits, plain); -+ rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, nbits, plain); - mpi_free (plain); - plain = NULL; - if (!rc) -@@ -1503,7 +1517,7 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_ - - case PUBKEY_ENC_OAEP: - rc = _gcry_rsa_oaep_decode (&unpad, &unpadlen, -- ctx.nbits, ctx.hash_algo, -+ nbits, ctx.hash_algo, - plain, ctx.label, ctx.labellen); - mpi_free (plain); - plain = NULL; -@@ -1548,9 +1562,13 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_ - RSA_public_key pk; - gcry_mpi_t sig = NULL; - gcry_mpi_t result = NULL; -+ unsigned int nbits = rsa_get_nbits (keyparms); -+ -+ rc = rsa_check_keysize (nbits); -+ if (rc) -+ return rc; - -- _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, -- rsa_get_nbits (keyparms)); -+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, nbits); - - /* Extract the data. */ - rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx); -@@ -1588,7 +1606,7 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_ - if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING)) - secret (sig, data, &sk); - else -- secret_blinded (sig, data, &sk, ctx.nbits); -+ secret_blinded (sig, data, &sk, nbits); - if (DBG_CIPHER) - log_printmpi ("rsa_sign res", sig); - -@@ -1650,9 +1668,13 @@ rsa_verify (gcry_sexp_t s_sig, gcry_sexp - gcry_mpi_t data = NULL; - RSA_public_key pk = { NULL, NULL }; - gcry_mpi_t result = NULL; -+ unsigned int nbits = rsa_get_nbits (keyparms); -+ -+ rc = rsa_check_keysize (nbits); -+ if (rc) -+ return rc; - -- _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, -- rsa_get_nbits (keyparms)); -+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, nbits); - - /* Extract the data. */ - rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx); -Index: libgcrypt-1.9.4/tests/basic.c -=================================================================== ---- libgcrypt-1.9.4.orig/tests/basic.c -+++ libgcrypt-1.9.4/tests/basic.c -@@ -14172,6 +14172,62 @@ check_pubkey (void) - "\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" } - }, - { -+ GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN | FLAG_GRIP, /* 2k RSA */ -+ { -+ "(private-key" -+ " (rsa" -+ " (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" -+ " 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" -+ " 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" -+ " 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" -+ " DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" -+ " 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" -+ " 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" -+ " 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6" -+ " CB#)\n" -+ " (e #010001#)\n" -+ " (d #07EF82500C403899934FE993AC5A36F14FF2DF38CF1EF315F205EE4C83EDAA19" -+ " 8890FC23DE9AA933CAFB37B6A8A8DBA675411958337287310D3FF2F1DDC0CB93" -+ " 7E70F57F75F833C021852B631D2B9A520E4431A03C5C3FCB5742DCD841D9FB12" -+ " 771AA1620DCEC3F1583426066ED9DC3F7028C5B59202C88FDF20396E2FA0EC4F" -+ " 5A22D9008F3043673931BC14A5046D6327398327900867E39CC61B2D1AFE2F48" -+ " EC8E1E3861C68D257D7425F4E6F99ABD77D61F10CA100EFC14389071831B33DD" -+ " 69CC8EABEF860D1DC2AAA84ABEAE5DFC91BC124DAF0F4C8EF5BBEA436751DE84" -+ " 3A8063E827A024466F44C28614F93B0732A100D4A0D86D532FE1E22C7725E401" -+ " #)\n" -+ " (p #00C29D438F115825779631CD665A5739367F3E128ADC29766483A46CA80897E0" -+ " 79B32881860B8F9A6A04C2614A904F6F2578DAE13EA67CD60AE3D0AA00A1FF9B" -+ " 441485E44B2DC3D0B60260FBFE073B5AC72FAF67964DE15C8212C389D20DB9CF" -+ " 54AF6AEF5C4196EAA56495DD30CF709F499D5AB30CA35E086C2A1589D6283F17" -+ " 83#)\n" -+ " (q #00D1984135231CB243FE959C0CBEF551EDD986AD7BEDF71EDF447BE3DA27AF46" -+ " 79C974A6FA69E4D52FE796650623DE70622862713932AA2FD9F2EC856EAEAA77" -+ " 88B4EA6084DC81C902F014829B18EA8B2666EC41586818E0589E18876065F97E" -+ " 8D22CE2DA53A05951EC132DCEF41E70A9C35F4ACC268FFAC2ADF54FA1DA110B9" -+ " 19#)\n" -+ " (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04" -+ " 479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4" -+ " A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9" -+ " AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7" -+ " #)))\n", -+ -+ "(public-key\n" -+ " (rsa\n" -+ " (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC" -+ " 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8" -+ " 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C" -+ " 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917" -+ " DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613" -+ " 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C" -+ " 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918" -+ " 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6" -+ " CB#)\n" -+ " (e #010001#)))\n", -+ -+ "\xe0\x08\x98\x9b\xb6\x44\xa2\x9a\x83\x37" -+ "\x47\xdd\x69\x55\xdb\x3a\xac\x89\x6e\x40"} -+ }, -+ { - GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT | FLAG_GRIP, - { - "(private-key\n" diff --git a/libgcrypt_indicators_changes.patch b/libgcrypt-FIPS-SLI-hash-mac.patch similarity index 80% rename from libgcrypt_indicators_changes.patch rename to libgcrypt-FIPS-SLI-hash-mac.patch index 53010cc..b12abc2 100644 --- a/libgcrypt_indicators_changes.patch +++ b/libgcrypt-FIPS-SLI-hash-mac.patch @@ -1,8 +1,8 @@ -diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi -index afb8a05..c613577 100644 ---- a/doc/gcrypt.texi -+++ b/doc/gcrypt.texi -@@ -968,23 +968,39 @@ is approved under the current FIPS 140-3 certification. If the +Index: libgcrypt-1.10.0/doc/gcrypt.texi +=================================================================== +--- libgcrypt-1.10.0.orig/doc/gcrypt.texi ++++ libgcrypt-1.10.0/doc/gcrypt.texi +@@ -980,23 +980,39 @@ is approved under the current FIPS 140-3 combination is approved, this function returns @code{GPG_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED} is returned. @@ -52,11 +52,11 @@ index afb8a05..c613577 100644 @code{GPG_ERR_NOT_SUPPORTED} is returned. @end table -diff --git a/src/fips.c b/src/fips.c -index f523e7d..d5ca482 100644 ---- a/src/fips.c -+++ b/src/fips.c -@@ -452,6 +452,7 @@ _gcry_fips_indicator_cipher (va_list arg_ptr) +Index: libgcrypt-1.10.0/src/fips.c +=================================================================== +--- libgcrypt-1.10.0.orig/src/fips.c ++++ libgcrypt-1.10.0/src/fips.c +@@ -357,6 +357,7 @@ _gcry_fips_indicator_cipher (va_list arg mode = va_arg (arg_ptr, enum gcry_cipher_modes); switch (mode) { @@ -64,7 +64,7 @@ index f523e7d..d5ca482 100644 case GCRY_CIPHER_MODE_ECB: case GCRY_CIPHER_MODE_CBC: case GCRY_CIPHER_MODE_CFB: -@@ -459,7 +460,6 @@ _gcry_fips_indicator_cipher (va_list arg_ptr) +@@ -364,7 +365,6 @@ _gcry_fips_indicator_cipher (va_list arg case GCRY_CIPHER_MODE_OFB: case GCRY_CIPHER_MODE_CTR: case GCRY_CIPHER_MODE_CCM: @@ -72,7 +72,7 @@ index f523e7d..d5ca482 100644 case GCRY_CIPHER_MODE_XTS: return GPG_ERR_NO_ERROR; default: -@@ -519,11 +519,25 @@ static const struct +@@ -422,11 +422,25 @@ static const struct { NULL, NULL} }; @@ -98,7 +98,7 @@ index f523e7d..d5ca482 100644 const char *curve_name; switch (alg) -@@ -531,13 +545,17 @@ _gcry_fips_indicator_pk (va_list arg_ptr) +@@ -434,13 +448,17 @@ _gcry_fips_indicator_pk (va_list arg_ptr case GCRY_PK_RSA: case GCRY_PK_RSA_E: case GCRY_PK_RSA_S: @@ -117,7 +117,7 @@ index f523e7d..d5ca482 100644 return GPG_ERR_NO_ERROR; } case GCRY_PK_ECC: -@@ -557,6 +575,60 @@ _gcry_fips_indicator_pk (va_list arg_ptr) +@@ -460,6 +478,62 @@ _gcry_fips_indicator_pk (va_list arg_ptr } } @@ -139,6 +139,8 @@ index f523e7d..d5ca482 100644 + case GCRY_MD_SHA3_256: + case GCRY_MD_SHA3_384: + case GCRY_MD_SHA3_512: ++ case GCRY_MD_SHAKE128: ++ case GCRY_MD_SHAKE256: + return GPG_ERR_NO_ERROR; + default: + return GPG_ERR_NOT_SUPPORTED; @@ -178,11 +180,11 @@ index f523e7d..d5ca482 100644 /* This is a test on whether the library is in the error or operational state. */ -diff --git a/src/g10lib.h b/src/g10lib.h -index 9fc868b..92c24a5 100644 ---- a/src/g10lib.h -+++ b/src/g10lib.h -@@ -488,7 +488,9 @@ void _gcry_fips_signal_error (const char *srcfile, +Index: libgcrypt-1.10.0/src/g10lib.h +=================================================================== +--- libgcrypt-1.10.0.orig/src/g10lib.h ++++ libgcrypt-1.10.0/src/g10lib.h +@@ -456,7 +456,9 @@ void _gcry_fips_signal_error (const char #endif int _gcry_fips_indicator_cipher (va_list arg_ptr); @@ -192,26 +194,26 @@ index 9fc868b..92c24a5 100644 int _gcry_fips_indicator_pk (va_list arg_ptr); int _gcry_fips_is_operational (void); -diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in -index 7704d17..344f879 100644 ---- a/src/gcrypt.h.in -+++ b/src/gcrypt.h.in -@@ -337,7 +337,9 @@ enum gcry_ctl_cmds - GCRYCTL_SET_ALLOW_WEAK_KEY = 79, +Index: libgcrypt-1.10.0/src/gcrypt.h.in +=================================================================== +--- libgcrypt-1.10.0.orig/src/gcrypt.h.in ++++ libgcrypt-1.10.0/src/gcrypt.h.in +@@ -331,7 +331,9 @@ enum gcry_ctl_cmds GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER = 81, GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82, -- GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 83 -+ GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 83, -+ GCRYCTL_FIPS_SERVICE_INDICATOR_HASH = 84, -+ GCRYCTL_FIPS_SERVICE_INDICATOR_MAC = 85 + GCRYCTL_NO_FIPS_MODE = 83, +- GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 84 ++ GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 84, ++ GCRYCTL_FIPS_SERVICE_INDICATOR_HASH = 85, ++ GCRYCTL_FIPS_SERVICE_INDICATOR_MAC = 86 }; /* Perform various operations defined by CMD. */ -diff --git a/src/global.c b/src/global.c -index c01b424..03756ea 100644 ---- a/src/global.c -+++ b/src/global.c -@@ -762,12 +762,24 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) +Index: libgcrypt-1.10.0/src/global.c +=================================================================== +--- libgcrypt-1.10.0.orig/src/global.c ++++ libgcrypt-1.10.0/src/global.c +@@ -791,12 +791,24 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, rc = _gcry_fips_indicator_cipher (arg_ptr); break; diff --git a/libgcrypt-FIPS-kdf-leylength.patch b/libgcrypt-FIPS-SLI-kdf-leylength.patch similarity index 80% rename from libgcrypt-FIPS-kdf-leylength.patch rename to libgcrypt-FIPS-SLI-kdf-leylength.patch index ceb8b64..fd415f4 100644 --- a/libgcrypt-FIPS-kdf-leylength.patch +++ b/libgcrypt-FIPS-SLI-kdf-leylength.patch @@ -1,8 +1,8 @@ -Index: libgcrypt-1.9.4/src/fips.c +Index: libgcrypt-1.10.0/src/fips.c =================================================================== ---- libgcrypt-1.9.4.orig/src/fips.c -+++ libgcrypt-1.9.4/src/fips.c -@@ -475,10 +475,15 @@ int +--- libgcrypt-1.10.0.orig/src/fips.c ++++ libgcrypt-1.10.0/src/fips.c +@@ -379,10 +379,15 @@ int _gcry_fips_indicator_kdf (va_list arg_ptr) { enum gcry_kdf_algos alg = va_arg (arg_ptr, enum gcry_kdf_algos); @@ -18,11 +18,11 @@ Index: libgcrypt-1.9.4/src/fips.c return GPG_ERR_NO_ERROR; default: return GPG_ERR_NOT_SUPPORTED; -Index: libgcrypt-1.9.4/doc/gcrypt.texi +Index: libgcrypt-1.10.0/doc/gcrypt.texi =================================================================== ---- libgcrypt-1.9.4.orig/doc/gcrypt.texi -+++ libgcrypt-1.9.4/doc/gcrypt.texi -@@ -983,10 +983,12 @@ algorithm supports different key sizes). +--- libgcrypt-1.10.0.orig/doc/gcrypt.texi ++++ libgcrypt-1.10.0/doc/gcrypt.texi +@@ -995,10 +995,12 @@ algorithm supports different key sizes). this function returns @code{GPS_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED} is returned. diff --git a/libgcrypt-FIPS-SLI-pk.patch b/libgcrypt-FIPS-SLI-pk.patch index d7b5ee6..a85f60c 100644 --- a/libgcrypt-FIPS-SLI-pk.patch +++ b/libgcrypt-FIPS-SLI-pk.patch @@ -1,22 +1,21 @@ -Index: libgcrypt-1.9.4/src/fips.c +Index: libgcrypt-1.10.0/src/fips.c =================================================================== ---- libgcrypt-1.9.4.orig/src/fips.c -+++ libgcrypt-1.9.4/src/fips.c -@@ -32,6 +32,7 @@ +--- libgcrypt-1.10.0.orig/src/fips.c ++++ libgcrypt-1.10.0/src/fips.c +@@ -36,6 +36,7 @@ #include "g10lib.h" #include "cipher-proto.h" +#include "cipher.h" - #include "hmac256.h" + #include "../random/random.h" - -@@ -482,6 +483,78 @@ _gcry_fips_indicator_kdf (va_list arg_pt + /* The states of the finite state machine used in fips mode. */ +@@ -386,6 +387,77 @@ _gcry_fips_indicator_kdf (va_list arg_pt default: return GPG_ERR_NOT_SUPPORTED; } +} + -+ +/* FIPS approved curves, extracted from: + * cipher/ecc-curves.c:curve_aliases[] and domain_parms[]. */ +static const struct @@ -89,25 +88,25 @@ Index: libgcrypt-1.9.4/src/fips.c } -Index: libgcrypt-1.9.4/src/gcrypt.h.in +Index: libgcrypt-1.10.0/src/gcrypt.h.in =================================================================== ---- libgcrypt-1.9.4.orig/src/gcrypt.h.in -+++ libgcrypt-1.9.4/src/gcrypt.h.in -@@ -336,7 +336,8 @@ enum gcry_ctl_cmds - GCRYCTL_AUTO_EXPAND_SECMEM = 78, - GCRYCTL_SET_ALLOW_WEAK_KEY = 79, +--- libgcrypt-1.10.0.orig/src/gcrypt.h.in ++++ libgcrypt-1.10.0/src/gcrypt.h.in +@@ -330,7 +330,8 @@ enum gcry_ctl_cmds + GCRYCTL_SET_DECRYPTION_TAG = 80, GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER = 81, -- GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82 -+ GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82, -+ GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 83 + GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82, +- GCRYCTL_NO_FIPS_MODE = 83 ++ GCRYCTL_NO_FIPS_MODE = 83, ++ GCRYCTL_FIPS_SERVICE_INDICATOR_PK = 84 }; /* Perform various operations defined by CMD. */ -Index: libgcrypt-1.9.4/doc/gcrypt.texi +Index: libgcrypt-1.10.0/doc/gcrypt.texi =================================================================== ---- libgcrypt-1.9.4.orig/doc/gcrypt.texi -+++ libgcrypt-1.9.4/doc/gcrypt.texi -@@ -975,6 +975,18 @@ certification. If the KDF is approved, t +--- libgcrypt-1.10.0.orig/doc/gcrypt.texi ++++ libgcrypt-1.10.0/doc/gcrypt.texi +@@ -987,6 +987,18 @@ certification. If the KDF is approved, t @code{GPG_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED} is returned. @@ -126,11 +125,11 @@ Index: libgcrypt-1.9.4/doc/gcrypt.texi @end table @end deftypefun -Index: libgcrypt-1.9.4/src/g10lib.h +Index: libgcrypt-1.10.0/src/g10lib.h =================================================================== ---- libgcrypt-1.9.4.orig/src/g10lib.h -+++ libgcrypt-1.9.4/src/g10lib.h -@@ -489,6 +489,7 @@ void _gcry_fips_signal_error (const char +--- libgcrypt-1.10.0.orig/src/g10lib.h ++++ libgcrypt-1.10.0/src/g10lib.h +@@ -457,6 +457,7 @@ void _gcry_fips_signal_error (const char int _gcry_fips_indicator_cipher (va_list arg_ptr); int _gcry_fips_indicator_kdf (va_list arg_ptr); @@ -138,11 +137,11 @@ Index: libgcrypt-1.9.4/src/g10lib.h int _gcry_fips_is_operational (void); -Index: libgcrypt-1.9.4/src/global.c +Index: libgcrypt-1.10.0/src/global.c =================================================================== ---- libgcrypt-1.9.4.orig/src/global.c -+++ libgcrypt-1.9.4/src/global.c -@@ -768,6 +768,15 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, +--- libgcrypt-1.10.0.orig/src/global.c ++++ libgcrypt-1.10.0/src/global.c +@@ -797,6 +797,15 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, rc = _gcry_fips_indicator_kdf (arg_ptr); break; diff --git a/libgcrypt-FIPS-Zeroize-hmac.patch b/libgcrypt-FIPS-Zeroize-hmac.patch deleted file mode 100644 index 680c29d..0000000 --- a/libgcrypt-FIPS-Zeroize-hmac.patch +++ /dev/null @@ -1,35 +0,0 @@ -Index: libgcrypt-1.9.4/src/fips.c -=================================================================== ---- libgcrypt-1.9.4.orig/src/fips.c -+++ libgcrypt-1.9.4/src/fips.c -@@ -905,6 +905,10 @@ check_binary_integrity (void) - char *fname = NULL; - const char key[] = "orboDeJITITejsirpADONivirpUkvarP"; - -+ /* A buffer of 64 bytes plus one for a LF and one to -+ * detect garbage. */ -+ unsigned char buffer[64+1+1]; -+ - if (get_library_path ("libgcrypt.so.20", "gcry_check_version", libpath, sizeof(libpath))) - err = gpg_error_from_syserror (); - else -@@ -927,9 +931,6 @@ check_binary_integrity (void) - err = gpg_error_from_syserror (); - else - { -- /* A buffer of 64 bytes plus one for a LF and one to -- detect garbage. */ -- unsigned char buffer[64+1+1]; - const unsigned char *s; - int n; - -@@ -957,6 +958,9 @@ check_binary_integrity (void) - } - } - } -+ /* Zeroize digest and buffer */ -+ memset (digest, 0, sizeof(digest)); -+ memset (buffer, 0, sizeof(buffer)); - reporter ("binary", 0, fname, err? gpg_strerror (err):NULL); - #ifdef HAVE_SYSLOG - if (err) diff --git a/libgcrypt-FIPS-disable-3DES.patch b/libgcrypt-FIPS-disable-3DES.patch deleted file mode 100644 index 47567f1..0000000 --- a/libgcrypt-FIPS-disable-3DES.patch +++ /dev/null @@ -1,52 +0,0 @@ -Index: libgcrypt-1.9.4/cipher/des.c -=================================================================== ---- libgcrypt-1.9.4.orig/cipher/des.c -+++ libgcrypt-1.9.4/cipher/des.c -@@ -1498,7 +1498,7 @@ static gcry_cipher_oid_spec_t oids_tripl - - gcry_cipher_spec_t _gcry_cipher_spec_tripledes = - { -- GCRY_CIPHER_3DES, {0, 1}, -+ GCRY_CIPHER_3DES, {0, 0}, - "3DES", NULL, oids_tripledes, 8, 192, sizeof (struct _tripledes_ctx), - do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt, - NULL, NULL, -Index: libgcrypt-1.9.4/cipher/mac-cmac.c -=================================================================== ---- libgcrypt-1.9.4.orig/cipher/mac-cmac.c -+++ libgcrypt-1.9.4/cipher/mac-cmac.c -@@ -458,7 +458,7 @@ gcry_mac_spec_t _gcry_mac_type_spec_cmac - #endif - #if USE_DES - gcry_mac_spec_t _gcry_mac_type_spec_cmac_tripledes = { -- GCRY_MAC_CMAC_3DES, {0, 1}, "CMAC_3DES", -+ GCRY_MAC_CMAC_3DES, {0, 0}, "CMAC_3DES", - &cmac_ops - }; - #endif -Index: libgcrypt-1.9.4/src/fips.c -=================================================================== ---- libgcrypt-1.9.4.orig/src/fips.c -+++ libgcrypt-1.9.4/src/fips.c -@@ -493,6 +493,10 @@ run_cipher_selftests (int extended) - - for (idx=0; algos[idx]; idx++) - { -+ /* Skip non-approved cipher in FIPS mode */ -+ if (fips_mode() && algos[idx] == GCRY_CIPHER_3DES) -+ continue; -+ - err = _gcry_cipher_selftest (algos[idx], extended, reporter); - reporter ("cipher", algos[idx], NULL, - err? gpg_strerror (err):NULL); -@@ -558,6 +562,10 @@ run_mac_selftests (int extended) - - for (idx=0; algos[idx]; idx++) - { -+ /* Skip non-approved MAC algorithm in FIPS mode */ -+ if (fips_mode() && algos[idx] == GCRY_MAC_CMAC_3DES) -+ continue; -+ - err = _gcry_mac_selftest (algos[idx], extended, reporter); - reporter ("mac", algos[idx], NULL, - err? gpg_strerror (err):NULL); diff --git a/libgcrypt-FIPS-disable-DSA.patch b/libgcrypt-FIPS-disable-DSA.patch deleted file mode 100644 index e43d6e8..0000000 --- a/libgcrypt-FIPS-disable-DSA.patch +++ /dev/null @@ -1,44 +0,0 @@ -From ea362090fc11caa28643153fc6444442243c8765 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Wed, 8 Dec 2021 09:52:02 +0900 -Subject: [PATCH 0937/1000] fips: Disable DSA in FIPS mode. - -* cipher/dsa.c (run_selftests): Disable DSA spec in FIPS mode. -* src/fips.c (run_pubkey_selftests): Skip DSA power-on selftests. --- - -GnuPG-bug-id: 5710 -Signed-off-by: Jakub Jelen ---- - cipher/dsa.c | 2 +- - src/fips.c | 1 - - 2 files changed, 1 insertion(+), 2 deletions(-) - -diff --git a/cipher/dsa.c b/cipher/dsa.c -index d5b00912..e559f9f5 100644 ---- a/cipher/dsa.c -+++ b/cipher/dsa.c -@@ -1441,7 +1441,7 @@ run_selftests (int algo, int extended, selftest_report_func_t report) - - gcry_pk_spec_t _gcry_pubkey_spec_dsa = - { -- GCRY_PK_DSA, { 0, 1 }, -+ GCRY_PK_DSA, { 0, 0 }, - GCRY_PK_USAGE_SIGN, - "DSA", dsa_names, - "pqgy", "pqgyx", "", "rs", "pqgy", -diff --git a/src/fips.c b/src/fips.c -index 0ab7fecc..bcadc5f2 100644 ---- a/src/fips.c -+++ b/src/fips.c -@@ -522,7 +522,6 @@ run_pubkey_selftests (int extended) - static int algos[] = - { - GCRY_PK_RSA, -- GCRY_PK_DSA, - GCRY_PK_ECC, - 0 - }; --- -2.34.1 - diff --git a/libgcrypt-FIPS-fix-gcry_mpi_sub_ui.patch b/libgcrypt-FIPS-fix-gcry_mpi_sub_ui.patch deleted file mode 100644 index 069ce75..0000000 --- a/libgcrypt-FIPS-fix-gcry_mpi_sub_ui.patch +++ /dev/null @@ -1,230 +0,0 @@ -From d5bf106468e6c6b0f33b193abf04590e4e9fc011 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Tue, 30 Nov 2021 22:04:16 +0200 -Subject: gcry_mpi_sub_ui: fix subtracting from negative value - -* mpi/mpi-add.c (_gcry_mpi_sub_ui): Set output sign bit when 'u' -is negative. -* tests/mpitests.c (test_add): Additional tests for mpi_add_ui; Check -test output and fail if output does not match expected. -(test_sub): Additional tests for mpi_sub_ui; Check test output and fail -if output does not match expected. -(test_mul): Additional tests for mpi_mul_ui; Check test output and fail -if output does not match expected. --- - -Reported-by: Guido Vranken -Signed-off-by: Jussi Kivilinna ---- - mpi/mpi-add.c | 1 + - tests/mpitests.c | 119 ++++++++++++++++++++++++++++++++++++++++++++--- - 2 files changed, 113 insertions(+), 7 deletions(-) - -diff --git a/mpi/mpi-add.c b/mpi/mpi-add.c -index 53f476e0..38dd352f 100644 ---- a/mpi/mpi-add.c -+++ b/mpi/mpi-add.c -@@ -191,6 +191,7 @@ _gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) - cy = _gcry_mpih_add_1(wp, up, usize, v); - wp[usize] = cy; - wsize = usize + cy; -+ wsign = 1; - } - else { /* The signs are different. Need exact comparison to determine - * which operand to subtract from which. */ -diff --git a/tests/mpitests.c b/tests/mpitests.c -index 96e01551..48ea18b2 100644 ---- a/tests/mpitests.c -+++ b/tests/mpitests.c -@@ -378,7 +378,8 @@ test_add (void) - gcry_mpi_t two; - gcry_mpi_t ff; - gcry_mpi_t result; -- unsigned char* pc; -+ gcry_mpi_t minusfive; -+ char *pc; - - gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); - gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); -@@ -386,21 +387,47 @@ test_add (void) - result = gcry_mpi_new(0); - - gcry_mpi_add(result, one, two); -- gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); - if (debug) - gcry_log_debug ("Result of one plus two:\n%s\n", pc); -+ if (strcmp (pc, "030303030303030303030303030303030303030303030303" -+ "030303030303030303030303030303030303030303030303") != 0) -+ fail ("mpi_add failed at line %d", __LINE__); - gcry_free(pc); - - gcry_mpi_add(result, ff, one); -- gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); - if (debug) - gcry_log_debug ("Result of ff plus one:\n%s\n", pc); -+ if (strcmp (pc, "010101010101010101010101010101010101010101010101" -+ "01010101010101010101010101010101010101010101010100") != 0) -+ fail ("mpi_add failed at line %d", __LINE__); -+ gcry_free(pc); -+ -+ gcry_mpi_scan(&minusfive, GCRYMPI_FMT_HEX, "-5", 0, NULL); -+ gcry_mpi_add_ui (result, minusfive, 2); -+ -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); -+ if (debug) -+ gcry_log_debug ("Result of minus five plus two:\n%s\n", pc); -+ if (strcmp (pc, "-03") != 0) -+ fail ("mpi_add_ui failed at line %d", __LINE__); -+ gcry_free(pc); -+ -+ gcry_mpi_add_ui (result, result, 3); -+ -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); -+ if (debug) -+ gcry_log_debug ("Result of minus three plus three:\n%s\n", pc); -+ if (strcmp (pc, "00") != 0) -+ fail ("mpi_add_ui failed at line %d", __LINE__); - gcry_free(pc); - - gcry_mpi_release(one); - gcry_mpi_release(two); - gcry_mpi_release(ff); - gcry_mpi_release(result); -+ gcry_mpi_release(minusfive); - return 1; - } - -@@ -408,24 +435,76 @@ test_add (void) - static int - test_sub (void) - { -+ gcry_mpi_t zero; - gcry_mpi_t one; - gcry_mpi_t two; -+ gcry_mpi_t five; - gcry_mpi_t result; -- unsigned char* pc; -+ gcry_mpi_t minusfive; -+ char *pc; - - gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); - gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); - result = gcry_mpi_new(0); - gcry_mpi_sub(result, two, one); - -- gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); - if (debug) - gcry_log_debug ("Result of two minus one:\n%s\n", pc); -+ if (strcmp (pc, "010101010101010101010101010101010101010101010101" -+ "010101010101010101010101010101010101010101010101") != 0) -+ fail ("mpi_sub failed at line %d", __LINE__); -+ gcry_free(pc); -+ -+ zero = gcry_mpi_new(0); -+ five = gcry_mpi_new(0); -+ minusfive = gcry_mpi_new(0); -+ gcry_mpi_set_ui (zero, 0); -+ gcry_mpi_set_ui (one, 1); -+ gcry_mpi_set_ui (two, 2); -+ gcry_mpi_set_ui (five, 5); -+ gcry_mpi_sub (minusfive, zero, five); -+ -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, minusfive); -+ if (debug) -+ gcry_log_debug ("Result of zero minus five:\n%s\n", pc); -+ if (strcmp (pc, "-05") != 0) -+ fail ("mpi_sub failed at line %d", __LINE__); -+ gcry_free(pc); -+ -+ gcry_mpi_sub_ui (result, five, 2); -+ -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); -+ if (debug) -+ gcry_log_debug ("Result of five minus two:\n%s\n", pc); -+ if (strcmp (pc, "03") != 0) -+ fail ("mpi_sub_ui failed at line %d", __LINE__); -+ gcry_free(pc); -+ -+ gcry_mpi_sub_ui (result, one, 10); -+ -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); -+ if (debug) -+ gcry_log_debug ("Result of one minus ten:\n%s\n", pc); -+ if (strcmp (pc, "-09") != 0) -+ fail ("mpi_sub_ui failed at line %d", __LINE__); -+ gcry_free(pc); -+ -+ gcry_mpi_sub_ui (result, minusfive, 2); -+ -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); -+ if (debug) -+ gcry_log_debug ("Result of minus five minus two:\n%s\n", pc); -+ if (strcmp (pc, "-07") != 0) -+ fail ("mpi_sub_ui failed at line %d", __LINE__); - gcry_free(pc); - - gcry_mpi_release(one); - gcry_mpi_release(two); - gcry_mpi_release(result); -+ gcry_mpi_release(zero); -+ gcry_mpi_release(five); -+ gcry_mpi_release(minusfive); - return 1; - } - -@@ -436,21 +515,47 @@ test_mul (void) - gcry_mpi_t two; - gcry_mpi_t three; - gcry_mpi_t result; -- unsigned char* pc; -+ gcry_mpi_t minusfive; -+ char *pc; - - gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); - gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL); - result = gcry_mpi_new(0); - gcry_mpi_mul(result, two, three); - -- gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); - if (debug) - gcry_log_debug ("Result of two mul three:\n%s\n", pc); -+ if (strcmp (pc, "060C12181E242A30363C42484E545A60666C72787E848A90" -+ "969CA2A8AEB4BAC0C6CCD2D8DEE4EAF0F6FD03090F151B21" -+ "1B150F0902FCF6F0EAE4DED8D2CCC6C0BAB4AEA8A29C9690" -+ "8A847E78726C66605A544E48423C36302A241E18120C06") != 0) -+ fail ("mpi_mul failed at line %d", __LINE__); -+ gcry_free(pc); -+ -+ gcry_mpi_scan(&minusfive, GCRYMPI_FMT_HEX, "-5", 0, NULL); -+ gcry_mpi_mul_ui (result, minusfive, 3); -+ -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); -+ if (debug) -+ gcry_log_debug ("Result of minus five mul three:\n%s\n", pc); -+ if (strcmp (pc, "-0F") != 0) -+ fail ("mpi_mul_ui failed at line %d", __LINE__); -+ gcry_free(pc); -+ -+ gcry_mpi_mul_ui (result, result, 0); -+ -+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, (unsigned char **)&pc, NULL, result); -+ if (debug) -+ gcry_log_debug ("Result of minus fifteen mul zero:\n%s\n", pc); -+ if (strcmp (pc, "00") != 0) -+ fail ("mpi_mul_ui failed at line %d", __LINE__); - gcry_free(pc); - - gcry_mpi_release(two); - gcry_mpi_release(three); - gcry_mpi_release(result); -+ gcry_mpi_release(minusfive); - return 1; - } - --- -2.33.1 - diff --git a/libgcrypt-FIPS-fix-regression-tests.patch b/libgcrypt-FIPS-fix-regression-tests.patch deleted file mode 100644 index 9f88fc9..0000000 --- a/libgcrypt-FIPS-fix-regression-tests.patch +++ /dev/null @@ -1,448 +0,0 @@ -Index: libgcrypt-1.9.4/cipher/pubkey.c -=================================================================== ---- libgcrypt-1.9.4.orig/cipher/pubkey.c -+++ libgcrypt-1.9.4/cipher/pubkey.c -@@ -224,7 +224,7 @@ check_pubkey_algo (int algo, unsigned us - gcry_pk_spec_t *spec; - - spec = spec_from_algo (algo); -- if (spec) -+ if (spec && !spec->flags.disabled) - { - if (((use & GCRY_PK_USAGE_SIGN) - && (! (spec->use & GCRY_PK_USAGE_SIGN))) -From 44c7c41af21c668826280abfee1257853020ba2d Mon Sep 17 00:00:00 2001 -From: NIIBE Yutaka -Date: Mon, 16 Aug 2021 12:41:11 +0900 -Subject: [PATCH 161/200] tests: Skip tests when FIPS for keygrip computations. - -* tests/keygrip.c (check): Skip non-FIPS curves when FIPS. -(main): Check if FIPS is enabled. - --- - -GnuPG-bug-id: 5520 -Signed-off-by: NIIBE Yutaka ---- - tests/keygrip.c | 37 ++++++++++++++++++++++++++++--------- - 1 file changed, 28 insertions(+), 9 deletions(-) - -diff --git a/tests/keygrip.c b/tests/keygrip.c -index cfccc06e..49bd71bc 100644 ---- a/tests/keygrip.c -+++ b/tests/keygrip.c -@@ -33,6 +33,9 @@ - - static int repetitions; - -+/* Whether fips mode was active at startup. */ -+static int in_fips_mode; -+ - - - static void -@@ -54,6 +57,7 @@ static struct - int algo; - const char *key; - const unsigned char grip[20]; -+ int skip_when_fips; - } key_grips[] = - { - { -@@ -155,7 +159,8 @@ static struct - /* */"436DD11A1756AFE56CD93408410FCDA9" - /* */"BA95024EB613BD481A14FCFEC27A448A#)))", - "\x52\xBA\xD4\xB4\xA3\x2D\x32\xA1\xDD\x06" -- "\x5E\x99\x0B\xF1\xAB\xC1\x13\x3D\x84\xD4" -+ "\x5E\x99\x0B\xF1\xAB\xC1\x13\x3D\x84\xD4", -+ 1 - }, - { /* Compressed form of above. */ - GCRY_PK_ECC, -@@ -165,7 +170,8 @@ static struct - " (q #022ECD8679930BE2DB4AD42B8600BA3F80" - /* */"2D4D539BFF2F69B83EC9B7BBAA7F3406#)))", - "\x52\xBA\xD4\xB4\xA3\x2D\x32\xA1\xDD\x06" -- "\x5E\x99\x0B\xF1\xAB\xC1\x13\x3D\x84\xD4" -+ "\x5E\x99\x0B\xF1\xAB\xC1\x13\x3D\x84\xD4", -+ 1 - }, - { - GCRY_PK_ECC, -@@ -177,7 +183,8 @@ static struct - /* */"9EBBA41915313417BA54218EB0569C59" - /* */"0B156C76DBCAB6E84575E6EF68CE7B87#)))", - "\x99\x38\x6A\x82\x41\x96\x29\x9C\x89\x74" -- "\xD6\xE1\xBF\x43\xAC\x9B\x9A\x12\xE7\x3F" -+ "\xD6\xE1\xBF\x43\xAC\x9B\x9A\x12\xE7\x3F", -+ 1 - }, - { /* Compressed form of above. */ - GCRY_PK_ECC, -@@ -187,7 +194,8 @@ static struct - " (q #035B784CA008EE64AB3D85017EE0D2BE87" - /* */"558762C7300E0C8E06B1F9AF7C031458#)))", - "\x99\x38\x6A\x82\x41\x96\x29\x9C\x89\x74" -- "\xD6\xE1\xBF\x43\xAC\x9B\x9A\x12\xE7\x3F" -+ "\xD6\xE1\xBF\x43\xAC\x9B\x9A\x12\xE7\x3F", -+ 1 - }, - { /* Ed25519 standard */ - GCRY_PK_ECC, -@@ -199,7 +207,8 @@ static struct - " 47BD24842905C049257673B3F5249524E0A41FAA17B25B818D0F97E625F1A1D0#)" - " ))", - "\x0C\xCA\xB2\xFD\x48\x9A\x33\x40\x2C\xE8" -- "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1" -+ "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1", -+ 1 - }, - { /* Ed25519+EdDSA */ - GCRY_PK_ECC, -@@ -209,7 +218,8 @@ static struct - " (q #773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" - " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" -- "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" -+ "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47", -+ 1 - }, - { /* Ed25519+EdDSA (with compression prefix) */ - GCRY_PK_ECC, -@@ -220,7 +230,8 @@ static struct - " 773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" - " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" -- "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" -+ "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47", -+ 1 - }, - { /* Ed25519+EdDSA (same but uncompressed)*/ - GCRY_PK_ECC, -@@ -232,7 +243,8 @@ static struct - " 5bb7c29018ece0f46b01f2960e99041a5779afe7e2292b65f9d51f8c84723e77#)" - " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" -- "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" -+ "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47", -+ 1 - }, - { /* Cv25519 */ - GCRY_PK_ECC, -@@ -243,7 +255,8 @@ static struct - " 918C1733127F6BF2646FAE3D081A18AE77111C903B906310B077505EFFF12740#)" - " ))", - "\x0F\x89\xA5\x65\xD3\xEA\x18\x7C\xE8\x39" -- "\x33\x23\x98\xF5\xD4\x80\x67\x7D\xF4\x9C" -+ "\x33\x23\x98\xF5\xD4\x80\x67\x7D\xF4\x9C", -+ 1 - }, - { /* Random key */ - GCRY_PK_RSA, -@@ -280,6 +293,9 @@ check (void) - - for (i = 0; i < (sizeof (key_grips) / sizeof (*key_grips)); i++) - { -+ if (in_fips_mode && key_grips[i].skip_when_fips) -+ continue; -+ - if (gcry_pk_test_algo (key_grips[i].algo)) - { - if (verbose) -@@ -379,6 +395,9 @@ main (int argc, char **argv) - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - check (); - - return 0; --- -2.33.0 - -From 3026148331523ec7ca81031339b5629431cafa23 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 09:20:18 +0200 -Subject: tests: Expect curves 25519/448 to fail in FIPS mode - -* tests/t-cv25519.c (test_cv_hl): Expect the operation to fail in FIPS - mode. - (test_cv_x25519, test_it): Ditto. - (main) Detect FIPS mode. -* tests/t-ed25519.c (one_test): Expect the operation to fail in FIPS - mode. - (main) Detect FIPS mode. -* tests/t-ed448.c (one_test): Expect the operation to fail in FIPS - mode. - (main) Detect FIPS mode. -* tests/t-x448.c (test_cv_hl): Expect the operation to fail in FIPS - mode. - (test_cv_x448, test_cv): Ditto. - (main) Detect FIPS mode. --- -The ed25519, ed448, cv25519 and cv448 curves are not available in FIPS -mode. Some of the tests already skipped these, but it is always better -to make sure thy are failing, rather than just skipping these. - -Signed-off-by: Jakub Jelen ---- - tests/t-cv25519.c | 37 +++++++++++++++++++++++++++++++++++-- - tests/t-ed25519.c | 18 ++++++++++++++---- - tests/t-ed448.c | 18 ++++++++++++++---- - tests/t-x448.c | 41 +++++++++++++++++++++++++++++++++++++---- - 4 files changed, 100 insertions(+), 14 deletions(-) - -diff --git a/tests/t-cv25519.c b/tests/t-cv25519.c -index 0de50a02..b4126f4c 100644 ---- a/tests/t-cv25519.c -+++ b/tests/t-cv25519.c -@@ -33,6 +33,7 @@ - #include "t-common.h" - #define N_TESTS 18 - -+static int in_fips_mode = 0; - - static void - print_mpi (const char *text, gcry_mpi_t a) -@@ -188,7 +189,17 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, - xfree (buffer); - buffer = NULL; - -- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) -+ err = gcry_pk_encrypt (&s_result, s_data, s_pk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_pk_encrypt failed for test %d: %s", testno, - gpg_strerror (err)); - -@@ -281,7 +292,17 @@ test_cv_x25519 (int testno, const char *k_str, const char *u_str, - goto leave; - } - -- if ((err = gcry_ecc_mul_point (algo, result, scalar, point))) -+ err = gcry_ecc_mul_point (algo, result, scalar, point); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_ecc_mul_point failed for test %d: %s", testno, - gpg_strerror (err)); - -@@ -335,6 +356,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) - info ("Running test %d: iteration=%d\n", testno, iter); - - gcry_mpi_ec_new (&ctx, NULL, "Curve25519"); -+ if (in_fips_mode) -+ { -+ if (ctx) -+ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ return; -+ } - Q = gcry_mpi_point_new (0); - - if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32) -@@ -640,6 +670,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - start_timer (); - check_cv25519 (); - stop_timer (); -diff --git a/tests/t-ed25519.c b/tests/t-ed25519.c -index a5271c25..567bc797 100644 ---- a/tests/t-ed25519.c -+++ b/tests/t-ed25519.c -@@ -36,6 +36,7 @@ - static int sign_with_pk; - static int no_verify; - static int custom_data_file; -+static int in_fips_mode = 0; - - - static void -@@ -271,7 +272,17 @@ one_test (int testno, const char *sk, const char *pk, - goto leave; - } - -- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) -+ err = gcry_pk_sign (&s_sig, s_msg, s_sk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); - if (debug) - show_sexp ("sig=", s_sig); -@@ -481,9 +492,8 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -- /* Ed25519 isn't supported in fips mode */ -- if (gcry_fips_mode_active()) -- return 77; -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - - start_timer (); - check_ed25519 (fname); -diff --git a/tests/t-ed448.c b/tests/t-ed448.c -index 1f445ffc..f38cd10c 100644 ---- a/tests/t-ed448.c -+++ b/tests/t-ed448.c -@@ -36,6 +36,7 @@ - static int sign_with_pk; - static int no_verify; - static int custom_data_file; -+static int in_fips_mode = 0; - - - static void -@@ -302,7 +303,17 @@ one_test (int testno, int ph, const char *sk, const char *pk, - } - } - -- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) -+ err = gcry_pk_sign (&s_sig, s_msg, s_sk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); - if (debug) - show_sexp ("sig=", s_sig); -@@ -521,9 +532,8 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -- /* Ed448 isn't supported in fips mode */ -- if (gcry_fips_mode_active()) -- return 77; -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - - start_timer (); - check_ed448 (fname); -diff --git a/tests/t-x448.c b/tests/t-x448.c -index 5c3cbeb9..cc4b10fc 100644 ---- a/tests/t-x448.c -+++ b/tests/t-x448.c -@@ -34,6 +34,7 @@ - #include "t-common.h" - #define N_TESTS 9 - -+static int in_fips_mode = 0; - - static void - print_mpi (const char *text, gcry_mpi_t a) -@@ -179,8 +180,18 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, - xfree (buffer); - buffer = NULL; - -- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) -- fail ("gcry_pk_encrypt failed for test %d: %s", testno, -+ err = gcry_pk_encrypt (&s_result, s_data, s_pk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) -+ fail ("gcry_pk_encrypt goto leavefailed for test %d: %s", testno, - gpg_strerror (err)); - - s_tmp = gcry_sexp_find_token (s_result, "s", 0); -@@ -257,7 +268,17 @@ test_cv_x448 (int testno, const char *k_str, const char *u_str, - goto leave; - } - -- if ((err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point))) -+ err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point); -+ if (in_fips_mode) -+ { -+ if (err != GPG_ERR_NOT_SUPPORTED) -+ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d: %s", -+ testno, gpg_strerror (err)); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_ecc_mul_point failed for test %d: %s", testno, - gpg_strerror (err)); - -@@ -296,7 +317,7 @@ test_cv (int testno, const char *k_str, const char *u_str, - static void - test_it (int testno, const char *k_str, int iter, const char *result_str) - { -- gcry_ctx_t ctx; -+ gcry_ctx_t ctx = NULL; - gpg_error_t err; - void *buffer = NULL; - size_t buflen; -@@ -311,6 +332,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) - info ("Running test %d: iteration=%d\n", testno, iter); - - gcry_mpi_ec_new (&ctx, NULL, "X448"); -+ if (in_fips_mode) -+ { -+ if (ctx) -+ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ return; -+ } - Q = gcry_mpi_point_new (0); - - if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 56) -@@ -583,6 +613,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - start_timer (); - check_x448 (); - stop_timer (); --- -2.33.0 - diff --git a/libgcrypt-FIPS-hw-optimizations.patch b/libgcrypt-FIPS-hw-optimizations.patch deleted file mode 100644 index 08f7727..0000000 --- a/libgcrypt-FIPS-hw-optimizations.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 70e6cec07d86332f1aaf7a69bec75c7138306f6a Mon Sep 17 00:00:00 2001 -From: NIIBE Yutaka -Date: Thu, 29 Jul 2021 14:20:14 +0900 -Subject: [PATCH] hwfeatures: Enable hardware support also in FIPS mode. - -* src/hwfeatures.c (_gcry_detect_hw_features): Remove skipping in FIPS -mode. - --- - -Reported-by: Jakub Jelen -GnuPG-bug-id: 5508 -Signed-off-by: NIIBE Yutaka ---- - src/hwfeatures.c | 3 --- - 1 file changed, 3 deletions(-) - -Index: libgcrypt-1.9.4/src/hwfeatures.c -=================================================================== ---- libgcrypt-1.9.4.orig/src/hwfeatures.c -+++ libgcrypt-1.9.4/src/hwfeatures.c -@@ -213,9 +213,6 @@ _gcry_detect_hw_features (void) - { - hw_features = 0; - -- if (fips_mode ()) -- return; /* Hardware support is not to be evaluated. */ -- - parse_hwf_deny_file (); - - #if defined (HAVE_CPU_ARCH_X86) diff --git a/libgcrypt-FIPS-module-version.patch b/libgcrypt-FIPS-module-version.patch deleted file mode 100644 index 7d8713c..0000000 --- a/libgcrypt-FIPS-module-version.patch +++ /dev/null @@ -1,89 +0,0 @@ -From c74fde0c3f6114c594332fb28a09c7b817969231 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 17 Sep 2021 17:11:30 +0200 -Subject: [PATCH 187/200] Allow passing FIPS module version - -* README: Document new --with-fips-module-version=version switch -* configure.ac: Implementation of the --with-fips-module-version -* src/global.c (print_config): Print FIPS module version from above --- -Signed-off-by: Jakub Jelen - -Moved the module version to a 3rd field to keep the semantics of that -line. - -Signed-off-by: Werner Koch -GnuPG-bug-id: 1600 ---- - README | 4 ++++ - configure.ac | 7 +++++++ - src/global.c | 16 +++++++++++++--- - 3 files changed, 24 insertions(+), 3 deletions(-) - -Index: libgcrypt-1.9.4/README -=================================================================== ---- libgcrypt-1.9.4.orig/README -+++ libgcrypt-1.9.4/README -@@ -165,6 +165,10 @@ - against a HMAC checksum. This works only in FIPS - mode and on systems providing the dladdr function. - -+ --with-fips-module-version=version -+ Specify a string used as a module version for FIPS -+ certification purposes. -+ - --disable-padlock-support - Disable support for the PadLock engine of VIA - processors. The default is to use PadLock if -Index: libgcrypt-1.9.4/configure.ac -=================================================================== ---- libgcrypt-1.9.4.orig/configure.ac -+++ libgcrypt-1.9.4/configure.ac -@@ -599,6 +599,12 @@ if test "$use_hmac_binary_check" = yes ; - [Define to support an HMAC based integrity check]) - fi - -+# Implementation of the --with-fips-module-version. -+AC_ARG_WITH(fips-module-version, -+ [ --with-fips-module-version=VERSION], -+ fips_module_version="$withval", fips_module_version="" ) -+AC_DEFINE_UNQUOTED(FIPS_MODULE_VERSION, "$fips_module_version", -+ [Define FIPS module version for certification]) - - # Implementation of the --disable-jent-support switch. - AC_MSG_CHECKING([whether jitter entropy support is requested]) -@@ -3266,6 +3272,7 @@ GCRY_MSG_WRAP([Enabled pubkey algorithms - GCRY_MSG_SHOW([Random number generator: ],[$random]) - GCRY_MSG_SHOW([Try using jitter entropy: ],[$jentsupport]) - GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities]) -+GCRY_MSG_SHOW([FIPS module version: ],[$fips_module_version]) - GCRY_MSG_SHOW([Try using Padlock crypto: ],[$padlocksupport]) - GCRY_MSG_SHOW([Try using AES-NI crypto: ],[$aesnisupport]) - GCRY_MSG_SHOW([Try using Intel SHAEXT: ],[$shaextsupport]) -Index: libgcrypt-1.9.4/src/global.c -=================================================================== ---- libgcrypt-1.9.4.orig/src/global.c -+++ libgcrypt-1.9.4/src/global.c -@@ -379,10 +379,19 @@ print_config (const char *what, gpgrt_st - { - /* We use y/n instead of 1/0 for the stupid reason that - * Emacsen's compile error parser would accidentally flag that -- * line when printed during "make check" as an error. */ -- gpgrt_fprintf (fp, "fips-mode:%c:%c:\n", -+ * line when printed during "make check" as an error. The -+ * second field is obsolete and thus empty (used to be used for -+ * a so-called enforced-fips-mode). The third field has an -+ * option static string describing the module versions; this is -+ * an optional configure option. */ -+ gpgrt_fprintf (fp, "fips-mode:%c::%s:\n", - fips_mode ()? 'y':'n', -- _gcry_enforced_fips_mode ()? 'y':'n' ); -+#ifdef FIPS_MODULE_VERSION -+ fips_mode () ? FIPS_MODULE_VERSION : "" -+#else -+ "" -+#endif /* FIPS_MODULE_VERSION */ -+ ); - } - - if (!what || !strcmp (what, "rng-type")) diff --git a/libgcrypt-FIPS-rndjent_poll.patch b/libgcrypt-FIPS-rndjent_poll.patch index a0bb5b7..f837842 100644 --- a/libgcrypt-FIPS-rndjent_poll.patch +++ b/libgcrypt-FIPS-rndjent_poll.patch @@ -1,8 +1,8 @@ -Index: libgcrypt-1.9.4/random/rndlinux.c +Index: libgcrypt-1.10.0/random/rndoldlinux.c =================================================================== ---- libgcrypt-1.9.4.orig/random/rndlinux.c -+++ libgcrypt-1.9.4/random/rndlinux.c -@@ -141,7 +141,7 @@ _gcry_rndlinux_gather_random (void (*add +--- libgcrypt-1.10.0.orig/random/rndoldlinux.c ++++ libgcrypt-1.10.0/random/rndoldlinux.c +@@ -132,7 +132,7 @@ _gcry_rndoldlinux_gather_random (void (* volatile pid_t apid; int fd; int n; @@ -11,7 +11,7 @@ Index: libgcrypt-1.9.4/random/rndlinux.c size_t n_hw; size_t want = length; size_t last_so_far = 0; -@@ -196,26 +196,43 @@ _gcry_rndlinux_gather_random (void (*add +@@ -187,26 +187,43 @@ _gcry_rndoldlinux_gather_random (void (* my_pid = apid; } @@ -71,7 +71,7 @@ Index: libgcrypt-1.9.4/random/rndlinux.c /* Open the requested device. The first time a device is to be opened we fail with a fatal error if the device does not exists. -@@ -283,8 +301,6 @@ _gcry_rndlinux_gather_random (void (*add +@@ -262,8 +279,6 @@ _gcry_rndoldlinux_gather_random (void (* do { nbytes = length < sizeof(buffer)? length : sizeof(buffer); @@ -80,10 +80,10 @@ Index: libgcrypt-1.9.4/random/rndlinux.c _gcry_pre_syscall (); ret = getentropy (buffer, nbytes); _gcry_post_syscall (); -Index: libgcrypt-1.9.4/random/rndjent.c +Index: libgcrypt-1.10.0/random/rndjent.c =================================================================== ---- libgcrypt-1.9.4.orig/random/rndjent.c -+++ libgcrypt-1.9.4/random/rndjent.c +--- libgcrypt-1.10.0.orig/random/rndjent.c ++++ libgcrypt-1.10.0/random/rndjent.c @@ -279,13 +279,24 @@ _gcry_rndjent_poll (void (*add)(const vo if (!jent_rng_is_initialized) { diff --git a/libgcrypt-FIPS-service-indicators.patch b/libgcrypt-FIPS-service-indicators.patch deleted file mode 100644 index ccbea90..0000000 --- a/libgcrypt-FIPS-service-indicators.patch +++ /dev/null @@ -1,375 +0,0 @@ -Index: libgcrypt-1.9.4/src/fips.c -=================================================================== ---- libgcrypt-1.9.4.orig/src/fips.c -+++ libgcrypt-1.9.4/src/fips.c -@@ -437,6 +437,54 @@ _gcry_fips_test_operational (void) - } - - -+int -+_gcry_fips_indicator_cipher (va_list arg_ptr) -+{ -+ enum gcry_cipher_algos alg = va_arg (arg_ptr, enum gcry_cipher_algos); -+ enum gcry_cipher_modes mode; -+ -+ switch (alg) -+ { -+ case GCRY_CIPHER_AES: -+ case GCRY_CIPHER_AES192: -+ case GCRY_CIPHER_AES256: -+ mode = va_arg (arg_ptr, enum gcry_cipher_modes); -+ switch (mode) -+ { -+ case GCRY_CIPHER_MODE_ECB: -+ case GCRY_CIPHER_MODE_CBC: -+ case GCRY_CIPHER_MODE_CFB: -+ case GCRY_CIPHER_MODE_CFB8: -+ case GCRY_CIPHER_MODE_OFB: -+ case GCRY_CIPHER_MODE_CTR: -+ case GCRY_CIPHER_MODE_CCM: -+ case GCRY_CIPHER_MODE_GCM: -+ case GCRY_CIPHER_MODE_XTS: -+ return GPG_ERR_NO_ERROR; -+ default: -+ return GPG_ERR_NOT_SUPPORTED; -+ } -+ default: -+ return GPG_ERR_NOT_SUPPORTED; -+ } -+} -+ -+ -+int -+_gcry_fips_indicator_kdf (va_list arg_ptr) -+{ -+ enum gcry_kdf_algos alg = va_arg (arg_ptr, enum gcry_kdf_algos); -+ -+ switch (alg) -+ { -+ case GCRY_KDF_PBKDF2: -+ return GPG_ERR_NO_ERROR; -+ default: -+ return GPG_ERR_NOT_SUPPORTED; -+ } -+} -+ -+ - /* This is a test on whether the library is in the error or - operational state. */ - int -Index: libgcrypt-1.9.4/src/g10lib.h -=================================================================== ---- libgcrypt-1.9.4.orig/src/g10lib.h -+++ libgcrypt-1.9.4/src/g10lib.h -@@ -487,6 +487,9 @@ void _gcry_fips_signal_error (const char - _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 1, (a)) - #endif - -+int _gcry_fips_indicator_cipher (va_list arg_ptr); -+int _gcry_fips_indicator_kdf (va_list arg_ptr); -+ - int _gcry_fips_is_operational (void); - - /* Return true if the library is in the operational state. */ -Index: libgcrypt-1.9.4/src/gcrypt.h.in -=================================================================== ---- libgcrypt-1.9.4.orig/src/gcrypt.h.in -+++ libgcrypt-1.9.4/src/gcrypt.h.in -@@ -334,7 +334,9 @@ enum gcry_ctl_cmds - GCRYCTL_GET_TAGLEN = 76, - GCRYCTL_REINIT_SYSCALL_CLAMP = 77, - GCRYCTL_AUTO_EXPAND_SECMEM = 78, -- GCRYCTL_SET_ALLOW_WEAK_KEY = 79 -+ GCRYCTL_SET_ALLOW_WEAK_KEY = 79, -+ GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER = 81, -+ GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82 - }; - - /* Perform various operations defined by CMD. */ -Index: libgcrypt-1.9.4/src/global.c -=================================================================== ---- libgcrypt-1.9.4.orig/src/global.c -+++ libgcrypt-1.9.4/src/global.c -@@ -755,6 +755,19 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - rc = _gcry_fips_run_selftests (1); - break; - -+ case GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER: -+ /* Get FIPS Service Indicator for a given symmetric algorithm and -+ * optional mode. Returns GPG_ERR_NO_ERROR if algorithm is allowed or -+ * GPG_ERR_NOT_SUPPORTED otherwise */ -+ rc = _gcry_fips_indicator_cipher (arg_ptr); -+ break; -+ -+ case GCRYCTL_FIPS_SERVICE_INDICATOR_KDF: -+ /* Get FIPS Service Indicator for a given KDF. Returns GPG_ERR_NO_ERROR -+ * if algorithm is allowed or GPG_ERR_NOT_SUPPORTED otherwise */ -+ rc = _gcry_fips_indicator_kdf (arg_ptr); -+ break; -+ - case PRIV_CTL_INIT_EXTRNG_TEST: /* Init external random test. */ - rc = GPG_ERR_NOT_SUPPORTED; - break; -Index: libgcrypt-1.9.4/tests/basic.c -=================================================================== ---- libgcrypt-1.9.4.orig/tests/basic.c -+++ libgcrypt-1.9.4/tests/basic.c -@@ -6383,6 +6383,16 @@ do_check_ocb_cipher (int inplace) - assert (tv[tidx].taglen <= ciphlen); - assert (tv[tidx].taglen <= sizeof tag); - -+ /* Verify the FIPS indicator marks this as non-approved */ -+ if (in_fips_mode) -+ { -+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, -+ tv[tidx].algo, GCRY_CIPHER_MODE_OCB); -+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) -+ fail ("cipher-ocb, gcry_control did not fail as expected (tv %d): %s\n", -+ tidx, gpg_strerror (err)); -+ } -+ - err = gcry_cipher_open (&hde, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) - err = gcry_cipher_open (&hdd, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0); -@@ -6644,6 +6654,16 @@ check_ocb_cipher_largebuf_split (int alg - memcpy(inbuf + i, hash, 16); - } - -+ /* Verify the FIPS indicator marks this as non-approved */ -+ if (in_fips_mode) -+ { -+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, -+ algo, GCRY_CIPHER_MODE_OCB); -+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) -+ fail ("cipher-ocb, gcry_control did not fail as expected (large, algo %d): %s\n", -+ algo, gpg_strerror (err)); -+ } -+ - err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) - err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); -@@ -6842,7 +6862,17 @@ check_ocb_cipher_checksum (int algo, int - blk[byteidx] |= 1 << bitpos; - } - -- err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); -+ /* Verify the FIPS indicator marks this as non-approved */ -+ if (in_fips_mode) -+ { -+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, -+ algo, GCRY_CIPHER_MODE_OCB); -+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) -+ fail ("cipher-ocb, gcry_control did not fail as expected (checksum, algo %d): %s\n", -+ algo, gpg_strerror (err)); -+ } -+ -+ err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) - err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) -@@ -7110,6 +7140,16 @@ check_ocb_cipher_splitaad (void) - aad[2] = tv[tidx].aad2? hex2buffer (tv[tidx].aad2, aadlen+2) : NULL; - aad[3] = tv[tidx].aad3? hex2buffer (tv[tidx].aad3, aadlen+3) : NULL; - -+ /* Verify the FIPS indicator marks this as non-approved */ -+ if (in_fips_mode) -+ { -+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, -+ GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OCB); -+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) -+ fail ("cipher-ocb-splitaad, gcry_control did not fail as expected: %s\n", -+ gpg_strerror (err)); -+ } -+ - err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OCB, 0); - if (err) - { -@@ -9044,6 +9084,17 @@ check_bulk_cipher_modes (void) - fprintf (stderr, " checking bulk encryption for %s [%i], mode %d\n", - gcry_cipher_algo_name (tv[i].algo), - tv[i].algo, tv[i].mode); -+ -+ /* Verify the FIPS indicator marks approved cipher/modes combinations */ -+ if (in_fips_mode) -+ { -+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER, -+ tv[i].algo, tv[i].mode); -+ if (gpg_err_code (err) != GPG_ERR_NO_ERROR) -+ fail ("gcry_control unexpectedly failed for algo = %s, mode = %d : %s\n", -+ gcry_cipher_algo_name (tv[i].algo), tv[i].mode, gpg_strerror (err)); -+ } -+ - err = gcry_cipher_open (&hde, tv[i].algo, tv[i].mode, 0); - if (!err) - err = gcry_cipher_open (&hdd, tv[i].algo, tv[i].mode, 0); -Index: libgcrypt-1.9.4/doc/gcrypt.texi -=================================================================== ---- libgcrypt-1.9.4.orig/doc/gcrypt.texi -+++ libgcrypt-1.9.4/doc/gcrypt.texi -@@ -961,6 +961,19 @@ been registered with Libgpg-error and ad - clamp again. Obviously this control code may only be used before a - second thread is started in a process. - -+@item GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER; Arguments: enum gcry_cipher_algos [, enum gcry_cipher_modes] -+ -+Check if the given symmetric cipher and optional cipher mode combination -+is approved under the current FIPS 140-3 certification. If the -+combination is approved, this function returns @code{GPG_ERR_NO_ERROR}. -+Otherwise @code{GPG_ERR_NOT_SUPPORTED} is returned. -+ -+@item GCRYCTL_FIPS_SERVICE_INDICATOR_KDF; Arguments: enum gcry_kdf_algos -+ -+Check if the given KDF is approved under the current FIPS 140-3 -+certification. If the KDF is approved, this function returns -+@code{GPG_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED} -+is returned. - - @end table - -@@ -980,7 +993,7 @@ descriptive message to the user and canc - - Some error values do not indicate a system error or an error in the - operation, but the result of an operation that failed properly. For --example, if you try to decrypt a tempered message, the decryption will -+example, if you try to decrypt a tampered message, the decryption will - fail. Another error value actually means that the end of a data - buffer or list has been reached. The following descriptions explain - for many error codes what they mean usually. Some error values have -@@ -6320,25 +6333,6 @@ The following symmetric encryption algor - power-up: - - @table @asis --@item 3DES --To test the 3DES 3-key EDE encryption in ECB mode these tests are --run: --@enumerate --@item --A known answer test is run on a 64 bit test vector processed by 64 --rounds of Single-DES block encryption and decryption using a key --changed with each round. --@item --A known answer test is run on a 64 bit test vector processed by 16 --rounds of 2-key and 3-key Triple-DES block encryption and decryptions --using a key changed with each round. --@item --10 known answer tests using 3-key Triple-DES EDE encryption, comparing --the ciphertext to the known value, then running a decryption and --comparing it to the initial plaintext. --@end enumerate --(@code{cipher/des.c:selftest}) -- - @item AES-128 - A known answer tests is run using one test vector and one test - key with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_128}) -@@ -6394,6 +6388,9 @@ A known answer test using 28 byte of dat - @item HMAC SHA-512 - A known answer test using 28 byte of data and a 4 byte key is run. - (@code{cipher/hmac-tests.c:selftests_sha512}) -+@item CMAC AES -+A known answer test using 40 byte of data and a 16 byte key is run. -+(@code{cipher/mac-cmac.c:selftests_cmac_aes}) - @end table - - @subsection Random Number Power-Up Test -@@ -6416,7 +6413,7 @@ The public key algorithms are tested dur - - @table @asis - @item RSA --A pre-defined 1024 bit RSA key is used and these tests are run -+A pre-defined 2048 bit RSA key is used and these tests are run - in turn: - @enumerate - @item -@@ -6426,14 +6423,14 @@ Conversion of S-expression to internal f - Private key consistency check. - (@code{cipher/@/rsa.c:@/selftests_rsa}) - @item --A pre-defined 20 byte value is signed with PKCS#1 padding for SHA-1. -+A pre-defined 20 byte value is signed with PKCS#1 padding for SHA-256. - The result is verified using the public key against the original data --and against modified data. (@code{cipher/@/rsa.c:@/selftest_sign_1024}) -+and against modified data. (@code{cipher/@/rsa.c:@/selftest_sign_2048}) - @item --A 1000 bit random value is encrypted and checked that it does not --match the original random value. The encrypted result is then -+A predefined 66 byte value is encrypted and checked that it matches -+reference encyrpted message. The encrypted result is then - decrypted and checked that it matches the original random value. --(@code{cipher/@/rsa.c:@/selftest_encr_1024}) -+(@code{cipher/@/rsa.c:@/selftest_encr_2048}) - @end enumerate - - @item DSA -@@ -6463,15 +6461,6 @@ of the same name but with a single dot a - @file{.hmac}. - - --@subsection Critical Functions Power-Up Tests -- --The 3DES weak key detection is tested during power-up by calling the --detection function with keys taken from a table listening all weak --keys. The table itself is protected using a SHA-1 hash. --(@code{cipher/@/des.c:@/selftest}) -- -- -- - @c -------------------------------- - @section Conditional Tests - -@@ -6645,8 +6634,6 @@ If Libgcrypt is used in FIPS mode these - The cryptographic algorithms are restricted to this list: - - @table @asis --@item GCRY_CIPHER_3DES --3 key EDE Triple-DES symmetric encryption. - @item GCRY_CIPHER_AES128 - AES 128 bit symmetric encryption. - @item GCRY_CIPHER_AES192 -@@ -6673,6 +6660,8 @@ HMAC using a SHA-256 message digest. - HMAC using a SHA-384 message digest. - @item GCRY_MD_SHA512,GCRY_MD_FLAG_HMAC - HMAC using a SHA-512 message digest. -+@item GCRY_MAC_CMAC_AES -+CMAC using a AES key. - @item GCRY_PK_RSA - RSA encryption and signing. - @item GCRY_PK_DSA -@@ -6683,8 +6672,8 @@ Note that the CRC algorithms are not con - and thus are in addition available. - - @item --RSA key generation refuses to create a key with a keysize of --less than 1024 bits. -+RSA key generation refuses to create and uyse ea key with a keysize of -+less than 2048 bits. - - @item - DSA key generation refuses to create a key with a keysize other -@@ -6697,8 +6686,9 @@ The @code{transient-key} flag for RSA an - Support for the VIA Padlock engine is disabled. - - @item --FIPS mode may only be used on systems with a /dev/random device. --Switching into FIPS mode on other systems will fail at runtime. -+FIPS mode may only be used on systems with a /dev/random device or -+with a getentropy syscall. Switching into FIPS mode on other systems -+will fail at runtime. - - @item - Saving and loading a random seed file is ignored. -@@ -6731,11 +6721,15 @@ disables FIPS mode unless Enforced FIPS - Libgcrypt will enter the error state. - - @item -+The signatures using SHA-1 digest algorithm may not be used. -+ -+@item - In Enforced FIPS mode the command @code{GCRYCTL_DISABLE_SECMEM} is - ignored. In standard FIPS mode it disables FIPS mode. - - @item - A handler set by @code{gcry_set_outofcore_handler} is ignored. -+ - @item - A handler set by @code{gcry_set_fatalerror_handler} is ignored. - diff --git a/libgcrypt-FIPS-verify-unsupported-KDF-test.patch b/libgcrypt-FIPS-verify-unsupported-KDF-test.patch deleted file mode 100644 index 46bba96..0000000 --- a/libgcrypt-FIPS-verify-unsupported-KDF-test.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0ab4e8063729147fb9abd463055785aac831bf5c Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 16:58:54 +0200 -Subject: [PATCH 348/500] tests: Verify unsupported KDF tests fail in FIPS mode - -* tests/t-kdf.c (check_pbkdf2): Verify tests based on algorithms - unsupported in FIPS mode fail. --- - -Signed-off-by: Jakub Jelen ---- - tests/t-kdf.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -Index: libgcrypt-1.9.4/tests/t-kdf.c -=================================================================== ---- libgcrypt-1.9.4.orig/tests/t-kdf.c -+++ libgcrypt-1.9.4/tests/t-kdf.c -@@ -998,7 +998,7 @@ check_pbkdf2 (void) - "\xa5\x7a\xe5\xa6\x08\x83\x96\xd1\x20\x85\x0c\x5c\x09\xde\x0a\x52" - "\x51\x00\x93\x8a\x59\xb1\xb5\xc3\xf7\x81\x09\x10\xd0\x5f\xcd\x97" - }, */ -- { -+ /* { -- not FIPS approved - "passwordPASSWORDpassword", 24, - "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, - GCRY_MD_GOSTR3411_CP, -@@ -1007,7 +1007,7 @@ check_pbkdf2 (void) - "\x78\x83\x58\xc6\x9c\xb2\xdb\xe2\x51\xa7\xbb\x17\xd5\xf4\x24\x1f" - "\x26\x5a\x79\x2a\x35\xbe\xcd\xe8\xd5\x6f\x32\x6b\x49\xc8\x50\x47" - "\xb7\x63\x8a\xcb\x47\x64\xb1\xfd" -- }, -+ }, */ - { - "pass\0word", 9, - "sa\0lt", 5, -@@ -1061,7 +1061,7 @@ check_pbkdf2 (void) - "\x1a\xdb\x60\x1c\x7e\x2a\x31\x4e\x8c\xb7\xb1\xe9\xdf\x84\x0e\x36" - "\xab\x56\x15\xbe\x5d\x74\x2b\x6c\xf2\x03\xfb\x55\xfd\xc4\x80\x71" - }, */ -- { -+ /* { -- not FIPS approved - "passwordPASSWORDpassword", 24, - "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, - GCRY_MD_STRIBOG512, -@@ -1074,7 +1074,7 @@ check_pbkdf2 (void) - "\xbd\x24\x21\xee\x9b\xb7\x11\x83\xba\x88\x2c\xee\xbf\xef\x25\x9f" - "\x33\xf9\xe2\x7d\xc6\x17\x8c\xb8\x9d\xc3\x74\x28\xcf\x9c\xc5\x2a" - "\x2b\xaa\x2d\x3a" -- }, -+ }, */ - { - "pass\0word", 9, - "sa\0lt", 5, -@@ -1104,6 +1104,13 @@ check_pbkdf2 (void) - GCRY_KDF_PBKDF2, tv[tvidx].hashalgo, - tv[tvidx].salt, tv[tvidx].saltlen, - tv[tvidx].c, tv[tvidx].dklen, outbuf); -+ if (gcry_fips_mode_active() && tvidx > 6) -+ { -+ if (!err) -+ fail ("pbkdf2 test %d unexpectedly passed in FIPS mode: %s\n", -+ tvidx, gpg_strerror (err)); -+ continue; -+ } - if (err) - fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err)); - else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) diff --git a/libgcrypt-PCT-DSA.patch b/libgcrypt-PCT-DSA.patch deleted file mode 100644 index ed0c27a..0000000 --- a/libgcrypt-PCT-DSA.patch +++ /dev/null @@ -1,118 +0,0 @@ -Index: libgcrypt-1.8.2/cipher/dsa.c -=================================================================== ---- libgcrypt-1.8.2.orig/cipher/dsa.c -+++ libgcrypt-1.8.2/cipher/dsa.c -@@ -181,24 +181,101 @@ test_keys (DSA_secret_key *sk, unsigned - /* Create a random plaintext. */ - _gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM); - -- /* Sign DATA using the secret key. */ -- sign (sig_a, sig_b, data, sk, 0, 0); -+ /* Use the gcry_pk_sign_md API in order to comply with FIPS 140-2, -+ * which requires full signature operation for PCT (hashing + -+ * asymmetric operation) */ -+ gcry_sexp_t s_skey = NULL; -+ gcry_sexp_t s_pkey = NULL; -+ gcry_sexp_t r_sig = NULL; -+ gcry_sexp_t s_hash = NULL; -+ gcry_md_hd_t hd = NULL; -+ gcry_mpi_t r_sig_mpi = NULL; -+ gcry_mpi_t s_sig_mpi = NULL; -+ unsigned char *buf = NULL; -+ size_t buflen; -+ -+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_pk_sign/open failed\n"); -+ goto leave; -+ } -+ -+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, data); -+ _gcry_md_write (hd, buf, buflen); -+ -+ xfree (buf); -+ buf = NULL; -+ -+ /* build DSA private key sexp in s_skey */ -+ sexp_build (&s_skey, NULL, "(private-key (dsa(p %m)(q %m)(g %m)(y %m)(x %m)))", -+ sk->p, sk->q, sk->g, sk->y, sk->x); -+ sexp_build (&s_hash, NULL, "(data (flags pkcs1)(hash-algo sha256))"); -+ if (_gcry_pk_sign_md (&r_sig, hd, s_hash, s_skey)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_pk_sign failed\n"); -+ goto leave; -+ } -+ -+ /* Check that the signature and the original plaintext differ. */ -+ if (_gcry_sexp_extract_param (r_sig, NULL, "rs", &r_sig_mpi, &s_sig_mpi, NULL)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("extracting signature data failed\n"); -+ goto leave; -+ } -+ -+ if ( !verify (r_sig_mpi, s_sig_mpi, data, &pk)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("Signature failed\n"); -+ goto leave; /* Signature matches but should not. */ -+ } -+ -+ _gcry_sexp_release (s_hash); -+ _gcry_md_close (hd); -+ -+ /* build DSA public key sexp in s_pkey */ -+ sexp_build (&s_pkey, NULL, "(public-key (dsa(p %m)(q %m)(g %m)(y %m)))", -+ pk.p, pk.q, pk.g, pk.y); -+ sexp_build (&s_hash, NULL, "(data (flags pkcs1)(hash-algo sha256))"); -+ -+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_md_open failed\n"); -+ } -+ -+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, data); -+ _gcry_md_write (hd, buf, buflen); -+ -+ xfree (buf); -+ buf = NULL; -+ -+ /* verify the signature */ -+ if (_gcry_pk_verify_md (r_sig, hd, s_hash, s_pkey)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_pk_verify failed\n"); -+ goto leave; /* Signature does not match. */ -+ } - -- /* Verify the signature using the public key. */ -- if ( verify (sig_a, sig_b, data, &pk) ) -- goto leave; /* Signature does not match. */ -- -- /* Modify the data and check that the signing fails. */ -- mpi_add_ui (data, data, 1); -- if ( !verify (sig_a, sig_b, data, &pk) ) -- goto leave; /* Signature matches but should not. */ -- -- result = 0; /* The test succeeded. */ -+ result = 0; /* The test succeeded. */ - - leave: - _gcry_mpi_release (sig_b); - _gcry_mpi_release (sig_a); - _gcry_mpi_release (data); -+ -+ _gcry_sexp_release (s_skey); -+ _gcry_sexp_release (s_pkey); -+ _gcry_sexp_release (s_hash); -+ _gcry_sexp_release (r_sig); -+ _gcry_mpi_release (r_sig_mpi); -+ _gcry_mpi_release (s_sig_mpi); -+ _gcry_md_close (hd); -+ - return result; - } - diff --git a/libgcrypt-PCT-ECC.patch b/libgcrypt-PCT-ECC.patch deleted file mode 100644 index 1d41e75..0000000 --- a/libgcrypt-PCT-ECC.patch +++ /dev/null @@ -1,342 +0,0 @@ -Index: libgcrypt-1.9.0/cipher/ecc.c -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/ecc.c -+++ libgcrypt-1.9.0/cipher/ecc.c -@@ -100,7 +100,7 @@ static void *progress_cb_data; - - - /* Local prototypes. */ --static void test_keys (mpi_ec_t ec, unsigned int nbits); -+static int test_keys (mpi_ec_t ec, unsigned int nbits); - static void test_ecdh_only_keys (mpi_ec_t ec, unsigned int nbits, int flags); - static unsigned int ecc_get_nbits (gcry_sexp_t parms); - -@@ -256,8 +256,10 @@ nist_generate_key (mpi_ec_t ec, int flag - else if (ec->model == MPI_EC_MONTGOMERY) - test_ecdh_only_keys (ec, ec->nbits - 63, flags); - else -- test_keys (ec, ec->nbits - 64); -- -+ { -+ if (test_keys (ec, ec->nbits - 64)) -+ return GPG_ERR_BAD_SIGNATURE; -+ } - return 0; - } - -@@ -268,9 +270,10 @@ nist_generate_key (mpi_ec_t ec, int flag - * test if the information is recuperated. - * Second, test with the sign and verify functions. - */ --static void -+static int - test_keys (mpi_ec_t ec, unsigned int nbits) - { -+ int result = -1; /* Default to failure. */ - gcry_mpi_t test = mpi_new (nbits); - mpi_point_struct R_; - gcry_mpi_t c = mpi_new (nbits); -@@ -285,23 +288,205 @@ test_keys (mpi_ec_t ec, unsigned int nbi - - _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM); - -- if (_gcry_ecc_ecdsa_sign (test, ec, r, s, 0, 0) ) -- log_fatal ("ECDSA operation: sign failed\n"); -+ /* Use the gcry_pk_sign_md API in order to comply with FIPS 140-2, -+ * which requires full signature operation for PCT (hashing + -+ * asymmetric operation). */ -+ gcry_sexp_t r_sig = NULL; -+ gcry_sexp_t s_skey = NULL; -+ gcry_sexp_t s_pkey = NULL; -+ gcry_sexp_t s_hash = NULL; -+ gcry_mpi_t s_sig_mpi = NULL; -+ gcry_md_hd_t hd = NULL; -+ unsigned char *buf = NULL; -+ size_t buflen; -+ mpi_ec_t ctx; -+ int flags = 0; -+ -+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_pk_sign failed: _gcry_md_open\n"); -+ } -+ -+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, test); -+ _gcry_md_write (hd, buf, buflen); -+ -+ xfree (buf); -+ buf = NULL; - -- if (_gcry_ecc_ecdsa_verify (test, ec, r, s)) -+ sexp_build (&s_hash, NULL, "(data (flags rfc6979)(hash-algo sha256))"); -+ -+ /* Assemble the point Q from affine coordinates by simple -+ * concatenation. */ -+ gcry_mpi_t Qx = NULL; -+ gcry_mpi_t Qy = NULL; -+ Qx = mpi_new (0); -+ Qy = mpi_new (0); -+ ctx = _gcry_mpi_ec_p_internal_new (ec->model, ec->dialect, flags, -+ ec->p, ec->a, ec->b); -+ if (_gcry_mpi_ec_get_affine (Qx, Qy, ec->Q, ctx)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("ecdh: Failed to get affine coordinates for Q\n"); -+ } -+ -+ unsigned char *rawqx, *rawqy; -+ unsigned int rawqxlen, rawqylen; -+ rawqx = _gcry_mpi_get_buffer (Qx, 0, &rawqxlen, NULL); -+ rawqy = _gcry_mpi_get_buffer (Qy, 0, &rawqylen, NULL); -+ -+ if (rawqxlen != rawqylen) -+ { -+ if (rawqxlen < rawqylen) -+ { -+ size_t diff = rawqylen - rawqxlen; -+ unsigned char *zeros = xmalloc (rawqxlen + diff); -+ memset (zeros, 0, rawqxlen + diff); -+ memmove (zeros + diff, rawqx, rawqxlen); -+ xfree (rawqx); -+ rawqx = zeros; -+ rawqxlen += diff; -+ } -+ if (rawqylen < rawqxlen) -+ { -+ size_t diff = rawqxlen - rawqylen; -+ unsigned char *zeros = xmalloc (rawqylen + diff); -+ memset (zeros, 0, rawqylen + diff); -+ memmove (zeros + diff, rawqy, rawqylen); -+ xfree (rawqy); -+ rawqy = zeros; -+ rawqylen += diff; -+ } -+ } -+ -+ unsigned char q[1 + rawqxlen + rawqxlen]; -+ size_t qlen; -+ memset (&q, 0, sizeof(q)); -+ *q = 4; -+ memcpy (q + 1, rawqx, rawqxlen); -+ memcpy (q + 1 + rawqxlen, rawqy, rawqylen); -+ qlen = 1 + rawqxlen + rawqylen; -+ -+ _gcry_mpi_release (Qx); -+ _gcry_mpi_release (Qy); -+ xfree (rawqx); -+ xfree (rawqy); -+ -+ /* build ECC private key sexp in s_skey */ -+ if (ec->name) -+ { -+ if (sexp_build (&s_skey, NULL, -+ "(private-key (ecc (curve %s)(d %m)(q %b)))", -+ ec->name, ec->d, qlen, q)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("ecc: Failed to build sexp for private key.\n"); -+ } -+ } -+ else -+ { -+ if (sexp_build (&s_skey, NULL, -+ "(private-key" -+ " (ecc (curve %s)(d %m)(p %m)(a %m)(b %m)(n %m)(h %m)(q %b)))", -+ "NIST P-512", ec->d, ec->p, ec->a, ec->b, ec->n, ec->h, -+ qlen, q)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("ecc: Failed to build sexp for private key.\n"); -+ } -+ } -+ if (_gcry_pk_sign_md (&r_sig, hd, s_hash, s_skey)) - { -- log_fatal ("ECDSA operation: sign, verify failed\n"); -+ if (DBG_CIPHER) -+ log_debug ("ecc: gcry_pk_sign failed\n"); -+ goto leave; -+ } -+ -+ /* Check that the signature and the original test differ. */ -+ if (_gcry_sexp_extract_param (r_sig, NULL, "s", &s_sig_mpi, NULL)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("extracting signature data failed\n"); -+ goto leave; -+ } -+ -+ if (!mpi_cmp (s_sig_mpi, test)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("Signature failed\n"); -+ goto leave; /* Signature and test match but should not. */ -+ } -+ -+ /* verify */ -+ /* build public key sexp in s_pkey */ -+ if (ec->name) -+ { -+ if (sexp_build (&s_pkey, NULL, -+ "(public-key (ecc (curve %s)(q %b)))", ec->name, qlen, q)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("ecc: Failed to build sexp for public key.\n"); -+ } -+ } -+ else -+ { -+ if (sexp_build (&s_pkey, NULL, -+ "(public-key" -+ " (ecc (curve %s)(p %m)(a %m)(b %m)(n %m)(h %m)(q %b)))", -+ "NIST P-512", ec->p, ec->a, ec->b, ec->n, ec->h, qlen, q)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("ecc: Failed to build sexp for private key.\n"); -+ } -+ } -+ -+ _gcry_md_close (hd); -+ -+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_pk_verify failed: _gcry_md_open\n"); -+ } -+ -+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, test); -+ _gcry_md_write (hd, buf, buflen); -+ -+ xfree (buf); -+ buf = NULL; -+ -+ /* verify the signature */ -+ if (_gcry_pk_verify_md (r_sig, hd, s_hash, s_pkey)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("ecc: gcry_pk_verify failed\n"); -+ goto leave; /* Signature does not match. */ - } - - if (DBG_CIPHER) -- log_debug ("ECDSA operation: sign, verify ok.\n"); -+ { -+ if (DBG_CIPHER) -+ log_debug ("ECDSA operation: sign, verify ok.\n"); -+ } -+ -+ result = 0; /* The test succeeded. */ - -+ leave: - point_free (&R_); - mpi_free (s); - mpi_free (r); - mpi_free (out); - mpi_free (c); - mpi_free (test); -+ -+ _gcry_sexp_release (r_sig); -+ _gcry_sexp_release (s_skey); -+ _gcry_sexp_release (s_pkey); -+ _gcry_sexp_release (s_hash); -+ _gcry_mpi_release (s_sig_mpi); -+ _gcry_md_close (hd); -+ xfree (ctx); -+ -+ return result; - } - - -Index: libgcrypt-1.9.0/cipher/pubkey.c -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/pubkey.c -+++ libgcrypt-1.9.0/cipher/pubkey.c -@@ -390,6 +390,7 @@ calculate_hash (gcry_md_hd_t hd, gcry_se - gcry_err_code_t rc; - const unsigned char *digest; - int algo; -+ const char *flags; - - if (!hd) - return 0; -@@ -398,16 +399,21 @@ calculate_hash (gcry_md_hd_t hd, gcry_se - if (rc) - return rc; - -+ rc = _gcry_pk_util_get_flags (*s_hash, &flags); -+ if (rc) -+ return rc; -+ - digest = _gcry_md_read(hd, algo); - if (!digest) - return GPG_ERR_DIGEST_ALGO; - - rc = _gcry_sexp_build (s_hash, NULL, -- "(data (flags pkcs1)(hash %s %b))", -+ "(data (flags %s)(hash %s %b))", flags, - _gcry_md_algo_name(algo), - (int) _gcry_md_get_algo_dlen(algo), - digest); - -+ xfree ((void *)flags); - return rc; - } - -Index: libgcrypt-1.9.0/cipher/pubkey-internal.h -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/pubkey-internal.h -+++ libgcrypt-1.9.0/cipher/pubkey-internal.h -@@ -45,6 +45,8 @@ gcry_err_code_t _gcry_pk_util_data_to_mp - struct pk_encoding_ctx *ctx); - gcry_err_code_t _gcry_pk_util_get_algo (gcry_sexp_t input, - int *algo); -+gcry_err_code_t _gcry_pk_util_get_flags (gcry_sexp_t input, -+ const char **flags); - - - -Index: libgcrypt-1.9.0/cipher/pubkey-util.c -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/pubkey-util.c -+++ libgcrypt-1.9.0/cipher/pubkey-util.c -@@ -1159,6 +1159,40 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t i - return rc; - } - -+gcry_err_code_t -+_gcry_pk_util_get_flags (gcry_sexp_t input, const char **flags) -+{ -+ gcry_err_code_t rc = 0; -+ gcry_sexp_t ldata, list = NULL; -+ -+ ldata = sexp_find_token (input, "data", 0); -+ if (!ldata) -+ { -+ rc = GPG_ERR_INV_OBJ; -+ goto leave; -+ } -+ -+ list = sexp_find_token (ldata, "flags", 0); -+ if (!list) -+ { -+ rc = GPG_ERR_INV_OBJ; -+ goto leave; -+ } -+ -+ /* FIXME: gets only the first flag */ -+ *flags = sexp_nth_string (list, 1); -+ if (!*flags) -+ { -+ rc = GPG_ERR_NO_OBJ; -+ goto leave; -+ } -+ -+ leave: -+ sexp_release (ldata); -+ sexp_release (list); -+ -+ return rc; -+} - - gcry_err_code_t - _gcry_pk_util_get_algo (gcry_sexp_t input, int *algo) diff --git a/libgcrypt-PCT-RSA.patch b/libgcrypt-PCT-RSA.patch deleted file mode 100644 index a2cb410..0000000 --- a/libgcrypt-PCT-RSA.patch +++ /dev/null @@ -1,123 +0,0 @@ -Index: libgcrypt-1.8.2/cipher/rsa.c -=================================================================== ---- libgcrypt-1.8.2.orig/cipher/rsa.c -+++ libgcrypt-1.8.2/cipher/rsa.c -@@ -159,22 +159,97 @@ test_keys (RSA_secret_key *sk, unsigned - /* Create another random plaintext as data for signature checking. */ - _gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM); - -- /* Use the RSA secret function to create a signature of the plaintext. */ -- secret (signature, plaintext, sk); -+ /* Use the gcry_pk_sign_md API in order to comply with FIPS 140-2, -+ * which requires full signature operation for PCT (hashing + -+ * asymmetric operation */ -+ gcry_sexp_t s_skey = NULL; -+ gcry_sexp_t s_pkey = NULL; -+ gcry_sexp_t r_sig = NULL; -+ gcry_sexp_t s_hash = NULL; -+ gcry_md_hd_t hd = NULL; -+ gcry_mpi_t r_sig_mpi = NULL; -+ unsigned char *buf = NULL; -+ size_t buflen; - -- /* Use the RSA public function to verify this signature. */ -- public (decr_plaintext, signature, &pk); -- if (mpi_cmp (decr_plaintext, plaintext)) -- goto leave; /* Signature does not match. */ -- -- /* Modify the signature and check that the signing fails. */ -- mpi_add_ui (signature, signature, 1); -- public (decr_plaintext, signature, &pk); -- if (!mpi_cmp (decr_plaintext, plaintext)) -- goto leave; /* Signature matches but should not. */ -+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_pk_sign/open failed\n"); -+ goto leave_hash; -+ } -+ -+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, plaintext); -+ _gcry_md_write (hd, buf, buflen); -+ -+ xfree (buf); -+ buf = NULL; -+ -+ /* build RSA private key sexp in s_skey */ -+ sexp_build (&s_skey, NULL, -+ "(private-key (rsa(n %m)(e %m)(d %m)(p %m)(q %m)))", -+ sk->n, sk->e, sk->d, sk->p, sk->q); -+ sexp_build (&s_hash, NULL, -+ "(data (flags pkcs1)(hash-algo sha256))"); -+ -+ if (_gcry_pk_sign_md (&r_sig, hd, s_hash, s_skey)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_pk_sign failed\n"); -+ goto leave_hash; -+ } -+ -+ /* Check that the signature and the original plaintext differ. */ -+ if (_gcry_sexp_extract_param (r_sig, "sig-val!rsa", "s", &r_sig_mpi, NULL)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("extracting signature data failed\n"); -+ goto leave_hash; -+ } -+ -+ if (!mpi_cmp (r_sig_mpi, plaintext)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("Signature failed\n"); -+ goto leave_hash; /* Signature and plaintext match but should not. */ -+ } -+ -+ _gcry_sexp_release (s_hash); -+ _gcry_md_close (hd); -+ -+ /* build RSA public key sexp in s_pkey */ -+ sexp_build (&s_pkey, NULL, "(public-key (rsa(n %m)(e %m)))", pk.n, pk.e); -+ sexp_build (&s_hash, NULL, "(data (flags pkcs1)(hash-algo sha256))"); -+ -+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_md_open failed\n"); -+ } -+ -+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, plaintext); -+ _gcry_md_write (hd, buf, buflen); -+ -+ xfree (buf); -+ buf = NULL; -+ -+ /* verify the signature */ -+ if (_gcry_pk_verify_md (r_sig, hd, s_hash, s_pkey)) -+ { -+ if (DBG_CIPHER) -+ log_debug ("gcry_pk_verify failed\n"); -+ goto leave_hash; /* Signature does not match. */ -+ } - - result = 0; /* All tests succeeded. */ - -+ leave_hash: -+ _gcry_sexp_release (s_skey); -+ _gcry_sexp_release (s_pkey); -+ _gcry_sexp_release (s_hash); -+ _gcry_sexp_release (r_sig); -+ _gcry_md_close (hd); -+ _gcry_mpi_release (r_sig_mpi); -+ - leave: - _gcry_mpi_release (signature); - _gcry_mpi_release (decr_plaintext); -@@ -1903,7 +1979,7 @@ selftest_encr_2048 (gcry_sexp_t pkey, gc - /* This sexp trickery is to prevent the use of blinding. - * The flag doesn't get inherited by encr, so we have to - * derive a new sexp from the ciphertext */ -- char buf[1024]; -+ unsigned char buf[1024]; - memset(buf, 0, sizeof(buf)); - err = _gcry_mpi_print (GCRYMPI_FMT_STD, buf, sizeof buf, NULL, ciphertext); - if (err) diff --git a/libgcrypt-Restore-self-tests-from-constructor.patch b/libgcrypt-Restore-self-tests-from-constructor.patch deleted file mode 100644 index ae72fac..0000000 --- a/libgcrypt-Restore-self-tests-from-constructor.patch +++ /dev/null @@ -1,16 +0,0 @@ -Index: libgcrypt-1.8.2/src/global.c -=================================================================== ---- libgcrypt-1.8.2.orig/src/global.c -+++ libgcrypt-1.8.2/src/global.c -@@ -140,8 +140,9 @@ global_init (void) - /* We always need the FSM lock to be functional. */ - _gcry_initialize_fsm_lock (); - -- /* Run the self-tests from the constructor. */ -- global_init (); -+ /* We run the integrity check at this point. The remaining -+ selftests are run before use of the library by application. */ -+ _gcry_fips_run_selftests (0); - } - - /* This function is called by the macro fips_is_operational and makes diff --git a/libgcrypt-dsa-rfc6979-test-fix.patch b/libgcrypt-dsa-rfc6979-test-fix.patch deleted file mode 100644 index e5d1988..0000000 --- a/libgcrypt-dsa-rfc6979-test-fix.patch +++ /dev/null @@ -1,124 +0,0 @@ -Index: libgcrypt-1.8.2/tests/benchmark.c -=================================================================== ---- libgcrypt-1.8.2.orig/tests/benchmark.c -+++ libgcrypt-1.8.2/tests/benchmark.c -@@ -1400,7 +1400,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", -+ const char *p_sizes[] = { "224", "256", "384", "521", "Ed25519", - "gost256", "gost512" }; - int testno; - -Index: libgcrypt-1.8.2/tests/dsa-rfc6979.c -=================================================================== ---- libgcrypt-1.8.2.orig/tests/dsa-rfc6979.c -+++ libgcrypt-1.8.2/tests/dsa-rfc6979.c -@@ -165,16 +165,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" -@@ -398,89 +388,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-ecc-ecdsa-no-blinding.patch b/libgcrypt-ecc-ecdsa-no-blinding.patch deleted file mode 100644 index 6536808..0000000 --- a/libgcrypt-ecc-ecdsa-no-blinding.patch +++ /dev/null @@ -1,82 +0,0 @@ -Index: libgcrypt-1.9.0/cipher/ecc.c -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/ecc.c -+++ libgcrypt-1.9.0/cipher/ecc.c -@@ -1581,11 +1581,11 @@ selftest_sign (gcry_sexp_t pkey, gcry_se - { - /* Sample data from RFC 6979 section A.2.5, hash is of message "sample" */ - static const char sample_data[] = -- "(data (flags rfc6979)" -+ "(data (flags rfc6979 no-blinding)" - " (hash sha256 #af2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915" - /**/ "62113d8a62add1bf#))"; - static const char sample_data_bad[] = -- "(data (flags rfc6979)" -+ "(data (flags rfc6979 no-blinding)" - " (hash sha256 #bf2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915" - /**/ "62113d8a62add1bf#))"; - static const char signature_r[] = -Index: libgcrypt-1.9.0/cipher/ecc-ecdsa.c -=================================================================== ---- libgcrypt-1.9.0.orig/cipher/ecc-ecdsa.c -+++ libgcrypt-1.9.0/cipher/ecc-ecdsa.c -@@ -51,6 +51,7 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, - unsigned int abits, qbits; - gcry_mpi_t b; /* Random number needed for blinding. */ - gcry_mpi_t bi; /* multiplicative inverse of B. */ -+ int with_blinding = !(flags & PUBKEY_FLAG_NO_BLINDING); - - if (DBG_CIPHER) - log_mpidump ("ecdsa sign hash ", input ); -@@ -64,12 +65,15 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, - - b = mpi_snew (qbits); - bi = mpi_snew (qbits); -- do -+ if (with_blinding) - { -- _gcry_mpi_randomize (b, qbits, GCRY_WEAK_RANDOM); -- mpi_mod (b, b, ec->n); -+ do -+ { -+ _gcry_mpi_randomize (b, qbits, GCRY_WEAK_RANDOM); -+ mpi_mod (b, b, ec->n); -+ } -+ while (!mpi_invm (bi, b, ec->n)); - } -- while (!mpi_invm (bi, b, ec->n)); - - k = NULL; - dr = mpi_alloc (0); -@@ -126,14 +130,23 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, - } - while (!mpi_cmp_ui (r, 0)); - -- /* Computation of dr, sum, and s are blinded with b. */ -- mpi_mulm (dr, b, ec->d, ec->n); -- mpi_mulm (dr, dr, r, ec->n); /* dr = d*r mod n */ -- mpi_mulm (sum, b, hash, ec->n); -- mpi_addm (sum, sum, dr, ec->n); /* sum = hash + (d*r) mod n */ -- mpi_mulm (s, k_1, sum, ec->n); /* s = k^(-1)*(hash+(d*r)) mod n */ -- /* Undo blinding by b^-1 */ -- mpi_mulm (s, bi, s, ec->n); -+ if (!with_blinding) -+ { -+ mpi_mulm (dr, ec->d, r, ec->n); /* dr = d*r mod n */ -+ mpi_addm (sum, hash, dr, ec->n); /* sum = hash + (d*r) mod n */ -+ } -+ else -+ { -+ mpi_mulm (dr, b, ec->d, ec->n); -+ mpi_mulm (dr, dr, r, ec->n); /* dr = d*r mod n */ -+ mpi_mulm (sum, b, hash, ec->n); -+ mpi_addm (sum, sum, dr, ec->n); /* sum = hash + (d*r) mod n */ -+ } -+ mpi_mulm (s, k_1, sum, ec->n); /* s = k^(-1)*(hash+(d*r)) mod n */ -+ if (with_blinding) -+ { -+ mpi_mulm (s, bi, s, ec->n); /* Undo blinding by b^-1 */ -+ } - } - while (!mpi_cmp_ui (s, 0)); - diff --git a/libgcrypt-fips_selftest_trigger_file.patch b/libgcrypt-fips_selftest_trigger_file.patch deleted file mode 100644 index 00442b9..0000000 --- a/libgcrypt-fips_selftest_trigger_file.patch +++ /dev/null @@ -1,40 +0,0 @@ -Index: libgcrypt-1.9.1/src/fips.c -=================================================================== ---- libgcrypt-1.9.1.orig/src/fips.c -+++ libgcrypt-1.9.1/src/fips.c -@@ -660,7 +660,7 @@ get_library_path(const char *libname, co - #endif - - static gpg_error_t --get_hmac_path(char **fname) -+get_hmac_path(char **fname, char *suffix) - { - char libpath[4096]; - gpg_error_t err; -@@ -685,7 +685,7 @@ get_hmac_path(char **fname) - p = *fname; - memmove (p+1, p, strlen (p)+1); - *p = '.'; -- strcat (*fname, ".hmac"); -+ strcat (*fname, suffix); - err = 0; - } - } -@@ -717,7 +717,7 @@ check_binary_integrity (void) - else - { - FILE *fp; -- err = get_hmac_path(&fname); -+ err = get_hmac_path(&fname, ".hmac"); - if (!err) - { - /* Open the file. */ -@@ -779,7 +779,7 @@ can_skip_selftests(void) - if (fips_mode()) - return 0; - -- if (get_hmac_path(&fname)) -+ if (get_hmac_path(&fname, ".fips")) - return 0; - - /* check the hmac presence */ diff --git a/libgcrypt-fipsdrv-enable-algo-for-dsa-sign.patch b/libgcrypt-fipsdrv-enable-algo-for-dsa-sign.patch deleted file mode 100644 index 054a0ff..0000000 --- a/libgcrypt-fipsdrv-enable-algo-for-dsa-sign.patch +++ /dev/null @@ -1,65 +0,0 @@ -Index: libgcrypt-1.6.1/tests/fipsdrv.c -=================================================================== ---- libgcrypt-1.6.1.orig/tests/fipsdrv.c -+++ libgcrypt-1.6.1/tests/fipsdrv.c -@@ -2190,11 +2190,12 @@ dsa_hash_from_key(gcry_sexp_t s_key) - return GCRY_MD_NONE; - } - -- -+ - /* Sign DATA of length DATALEN using the key taken from the S-expression - encoded KEYFILE. */ - static void --run_dsa_sign (const void *data, size_t datalen, const char *keyfile) -+run_dsa_sign (const void *data, size_t datalen, -+ int hashalgo, const char *keyfile) - - { - gpg_error_t err; -@@ -2202,13 +2203,20 @@ run_dsa_sign (const void *data, size_t d - char hash[128]; - gcry_mpi_t tmpmpi; - int algo; -+ int algo_len; -+ int hashalgo_len; - - s_key = read_sexp_from_file (keyfile); - algo = dsa_hash_from_key(s_key); -+ algo_len = gcry_md_get_algo_dlen(algo); -+ hashalgo_len = gcry_md_get_algo_dlen(hashalgo); - -- gcry_md_hash_buffer (algo, hash, data, datalen); -+ if (hashalgo_len < algo_len) -+ algo_len = hashalgo_len; -+ -+ gcry_md_hash_buffer (hashalgo, hash, data, datalen); - err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -- gcry_md_get_algo_dlen(algo), NULL); -+ algo_len, NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -3000,14 +3008,21 @@ main (int argc, char **argv) - } - else if (!strcmp (mode_string, "dsa-sign")) - { -+ int algo; -+ - if (!key_string) - die ("option --key is required in this mode\n"); - if (access (key_string, R_OK)) - die ("option --key needs to specify an existing keyfile\n"); -+ if (!algo_string) -+ die ("option --algo is required in this mode\n"); -+ algo = gcry_md_map_name (algo_string); -+ if (!algo) -+ die ("digest algorithm `%s' is not supported\n", algo_string); - if (!data) - die ("no data available (do not use --chunk)\n"); - -- run_dsa_sign (data, datalen, key_string); -+ run_dsa_sign (data, datalen, algo, key_string); - } - else if (!strcmp (mode_string, "dsa-verify")) - { diff --git a/libgcrypt-fipsdrv-enable-algo-for-dsa-verify.patch b/libgcrypt-fipsdrv-enable-algo-for-dsa-verify.patch deleted file mode 100644 index 2fb06f3..0000000 --- a/libgcrypt-fipsdrv-enable-algo-for-dsa-verify.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- libgcrypt-1.6.1-orig/tests/fipsdrv.c 2017-10-20 10:39:56.080098385 +0000 -+++ libgcrypt-1.6.1-orig/tests/fipsdrv.c 2017-10-20 10:41:15.780098385 +0000 -@@ -2288,7 +2288,7 @@ run_dsa_sign (const void *data, size_t d - S-expression in KEYFILE against the S-expression formatted - signature in SIGFILE. */ - static void --run_dsa_verify (const void *data, size_t datalen, -+run_dsa_verify (const void *data, size_t datalen, int hashalgo, - const char *keyfile, const char *sigfile) - - { -@@ -2297,15 +2297,23 @@ run_dsa_verify (const void *data, size_t - char hash[128]; - gcry_mpi_t tmpmpi; - int algo; -+ int algo_len; -+ int hashalgo_len; - - s_key = read_sexp_from_file (keyfile); - algo = dsa_hash_from_key(s_key); - -- gcry_md_hash_buffer (algo, hash, data, datalen); -+ algo_len = gcry_md_get_algo_dlen(algo); -+ hashalgo_len = gcry_md_get_algo_dlen(hashalgo); -+ -+ if (hashalgo_len < algo_len) -+ algo_len = hashalgo_len; -+ -+ gcry_md_hash_buffer (hashalgo, hash, data, datalen); - /* Note that we can't simply use %b with HASH to build the - S-expression, because that might yield a negative value. */ - err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -- gcry_md_get_algo_dlen(algo), NULL); -+ algo_len, NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -3011,10 +3019,17 @@ main (int argc, char **argv) - } - else if (!strcmp (mode_string, "dsa-verify")) - { -+ int algo; -+ - if (!key_string) - die ("option --key is required in this mode\n"); - if (access (key_string, R_OK)) - die ("option --key needs to specify an existing keyfile\n"); -+ if (!algo_string) -+ die ("option --algo is required in this mode\n"); -+ algo = gcry_md_map_name (algo_string); -+ if (!algo) -+ die ("digest algorithm `%s' is not supported\n", algo_string); - if (!data) - die ("no data available (do not use --chunk)\n"); - if (!signature_string) -@@ -3022,7 +3037,7 @@ main (int argc, char **argv) - if (access (signature_string, R_OK)) - die ("option --signature needs to specify an existing file\n"); - -- run_dsa_verify (data, datalen, key_string, signature_string); -+ run_dsa_verify (data, datalen, algo, key_string, signature_string); - } - else if (!strcmp (mode_string, "ecdsa-gen-key")) - { diff --git a/libgcrypt-fix-rng.patch b/libgcrypt-fix-rng.patch deleted file mode 100644 index 851b208..0000000 --- a/libgcrypt-fix-rng.patch +++ /dev/null @@ -1,24 +0,0 @@ -Index: libgcrypt-1.7.2/random/random.c -=================================================================== ---- libgcrypt-1.7.2.orig/random/random.c -+++ libgcrypt-1.7.2/random/random.c -@@ -419,6 +419,9 @@ _gcry_create_nonce (void *buffer, size_t - size_t n; - int err; - -+ /* Make sure we are initialized. */ -+ _gcry_random_initialize (1); -+ - /* First check whether we shall use the FIPS nonce generator. This - is only done in FIPS mode, in all other modes, we use our own - nonce generator which is seeded by the RNG actual in use. */ -@@ -433,9 +436,6 @@ _gcry_create_nonce (void *buffer, size_t - FIPS mode (not that this means it is also used if the FIPS RNG - has been selected but we are not in fips mode). */ - -- /* Make sure we are initialized. */ -- _gcry_random_initialize (1); -- - /* Acquire the nonce buffer lock. */ - err = gpgrt_lock_lock (&nonce_buffer_lock); - if (err) diff --git a/libgcrypt-fix-tests-fipsmode.patch b/libgcrypt-fix-tests-fipsmode.patch deleted file mode 100644 index c9706ba..0000000 --- a/libgcrypt-fix-tests-fipsmode.patch +++ /dev/null @@ -1,177 +0,0 @@ -Index: libgcrypt-1.9.1/tests/basic.c -=================================================================== ---- libgcrypt-1.9.1.orig/tests/basic.c -+++ libgcrypt-1.9.1/tests/basic.c -@@ -9978,7 +9978,7 @@ check_ciphers (void) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_EAX, 0); - if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0); -- if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) -+ if (!in_fips_mode && gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0); - if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_OCB_BLOCK_LEN) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0); -@@ -10025,12 +10025,18 @@ check_cipher_modes(void) - check_cfb_cipher (); - check_ofb_cipher (); - check_ccm_cipher (); -- check_gcm_cipher (); -- check_poly1305_cipher (); -- check_ocb_cipher (); -+ if (!in_fips_mode) -+ { -+ check_gcm_cipher (); -+ check_poly1305_cipher (); -+ check_ocb_cipher (); -+ } - check_xts_cipher (); - check_eax_cipher (); -- check_gost28147_cipher (); -+ if (!in_fips_mode) -+ { -+ check_gost28147_cipher (); -+ } - check_stream_cipher (); - check_stream_cipher_large_block (); - -@@ -13383,7 +13389,7 @@ check_mac (void) - show_mac_not_available (algos[i].algo); - continue; - } -- if (gcry_mac_test_algo (algos[i].algo) && in_fips_mode) -+ if ((algos[i].algo == GCRY_MAC_GMAC_AES || gcry_mac_test_algo (algos[i].algo)) && in_fips_mode) - { - if (verbose) - fprintf (stderr, " algorithm %d not available in fips mode\n", -@@ -14508,8 +14514,6 @@ main (int argc, char **argv) - /* If we are in fips mode do some more tests. */ - gcry_md_hd_t md; - -- /* First trigger a self-test. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); - if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("not in operational state after self-test\n"); - -@@ -14534,15 +14538,6 @@ main (int argc, char **argv) - gcry_md_close (md); - if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("expected error state but still in operational state\n"); -- else -- { -- /* Now run a self-test and to get back into -- operational state. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); -- if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) -- fail ("did not reach operational after error " -- "and self-test\n"); -- } - } - } - -Index: libgcrypt-1.9.1/tests/benchmark.c -=================================================================== ---- libgcrypt-1.9.1.orig/tests/benchmark.c -+++ libgcrypt-1.9.1/tests/benchmark.c -@@ -943,8 +943,10 @@ cipher_bench ( const char *algoname ) - && algo != GCRY_CIPHER_CHACHA20) - continue; - -- if (modes[modeidx].req_blocksize > 0 -- && blklen != modes[modeidx].req_blocksize) -+ if ((modes[modeidx].req_blocksize > 0 -+ && blklen != modes[modeidx].req_blocksize) -+ || (in_fips_mode -+ && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM)) - { - printf (" %7s %7s", "-", "-" ); - continue; -Index: libgcrypt-1.9.1/tests/bench-slope.c -=================================================================== ---- libgcrypt-1.9.1.orig/tests/bench-slope.c -+++ libgcrypt-1.9.1/tests/bench-slope.c -@@ -1573,7 +1573,7 @@ cipher_bench_one (int algo, struct bench - return; - - /* GCM has restrictions for block-size */ -- if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN) -+ if (mode.mode == GCRY_CIPHER_MODE_GCM && (gcry_fips_mode_active () || blklen != GCRY_GCM_BLOCK_LEN)) - return; - - /* XTS has restrictions for block-size */ -Index: libgcrypt-1.9.1/tests/pubkey.c -=================================================================== ---- libgcrypt-1.9.1.orig/tests/pubkey.c -+++ libgcrypt-1.9.1/tests/pubkey.c -@@ -504,15 +504,30 @@ get_dsa_key_with_domain_new (gcry_sexp_t - rc = gcry_sexp_new - (&key_spec, - "(genkey (dsa (transient-key)(domain" -- "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" -- "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" -- "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" -- "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" -- "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" -- "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" -- "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" -- "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" -- "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" -+ " (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#)" - ")))", 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gcry_strerror (rc)); -@@ -596,7 +611,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ - " (use-fips186)" - " (transient-key)" - " (derive-parms" -- " (seed #f770a4598ff756931fc529764513b103ce57d85f4ad8c5cf297c9b4d48241c5b#))))", -+ " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", - 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gcry_strerror (rc)); -Index: libgcrypt-1.9.1/tests/t-secmem.c -=================================================================== ---- libgcrypt-1.9.1.orig/tests/t-secmem.c -+++ libgcrypt-1.9.1/tests/t-secmem.c -@@ -174,7 +174,8 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0)); -- gcry_set_outofcore_handler (outofcore_handler, NULL); -+ if (!gcry_fips_mode_active ()) -+ gcry_set_outofcore_handler (outofcore_handler, NULL); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - - /* Libgcrypt prints a warning when the first overflow is allocated; -@@ -184,7 +185,8 @@ main (int argc, char **argv) - - - test_secmem (); -- test_secmem_overflow (); -+ if (!gcry_fips_mode_active ()) -+ test_secmem_overflow (); - /* FIXME: We need to improve the tests, for example by registering - * our own log handler and comparing the output of - * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */ diff --git a/libgcrypt-global_init-constructor.patch b/libgcrypt-global_init-constructor.patch deleted file mode 100644 index e72e606..0000000 --- a/libgcrypt-global_init-constructor.patch +++ /dev/null @@ -1,254 +0,0 @@ -Index: libgcrypt-1.9.1/src/global.c -=================================================================== ---- libgcrypt-1.9.1.orig/src/global.c -+++ libgcrypt-1.9.1/src/global.c -@@ -86,7 +86,7 @@ static gpg_err_code_t external_lock_test - likely to be called at startup. The suggested way for an - application to make sure that this has been called is by using - gcry_check_version. */ --static void -+static void __attribute__((constructor)) - global_init (void) - { - gcry_error_t err = 0; -@@ -134,6 +134,16 @@ global_init (void) - if (err) - goto fail; - -+ 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; -+ err = _gcry_fips_run_selftests (0); -+ no_secure_memory = no_secmem_save; -+ -+ if (err) -+ goto fail; -+ - return; - - fail: -@@ -141,16 +151,6 @@ global_init (void) - } - - --void __attribute__ ((constructor)) _gcry_global_constructor (void) --{ -- /* We always need the FSM lock to be functional. */ -- _gcry_initialize_fsm_lock (); -- -- /* We run the integrity check at this point. The remaining -- selftests are run before use of the library by application. */ -- _gcry_fips_run_selftests (0); --} -- - /* 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 -Index: libgcrypt-1.9.1/src/fips.c -=================================================================== ---- libgcrypt-1.9.1.orig/src/fips.c -+++ libgcrypt-1.9.1/src/fips.c -@@ -124,6 +124,7 @@ void - _gcry_initialize_fips_mode (int force) - { - static int done; -+ gpg_error_t err; - - /* Make sure we are not accidentally called twice. */ - if (done) -@@ -213,6 +214,23 @@ _gcry_initialize_fips_mode (int force) - /* Yes, we are in FIPS mode. */ - FILE *fp; - -+ /* Intitialize the lock to protect the FSM. */ -+ err = gpgrt_lock_init (&fsm_lock); -+ if (err) -+ { -+ /* If that fails we can't do anything but abort the -+ * process. We need to use log_info so that the FSM won't -+ * get involved. */ -+ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", -+ gpg_strerror (err)); -+#ifdef HAVE_SYSLOG -+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " -+ "creating FSM lock failed: %s - abort", -+ gpg_strerror (err)); -+#endif /*HAVE_SYSLOG*/ -+ abort (); -+ } -+ - /* If the FIPS force files exists, is readable and has a number - != 0 on its first line, we enable the enforced fips mode. */ - fp = fopen (FIPS_FORCE_FILE, "r"); -@@ -641,6 +659,39 @@ get_library_path(const char *libname, co - } - #endif - -+static gpg_error_t -+get_hmac_path(char **fname) -+{ -+ char libpath[4096]; -+ gpg_error_t err; -+ -+ if (get_library_path ("libgcrypt.so.20", "gcry_check_version", libpath, sizeof(libpath))) -+ err = gpg_error_from_syserror (); -+ else -+ { -+ *fname = _gcry_malloc (strlen (libpath) + 1 + 5 + 1 ); -+ if (!*fname) -+ err = gpg_error_from_syserror (); -+ else -+ { -+ char *p; -+ -+ /* Prefix the basename with a dot. */ -+ strcpy (*fname, libpath); -+ p = strrchr (*fname, '/'); -+ if (p) -+ p++; -+ else -+ p = *fname; -+ memmove (p+1, p, strlen (p)+1); -+ *p = '.'; -+ strcat (*fname, ".hmac"); -+ err = 0; -+ } -+ } -+ return err; -+} -+ - /* Run an integrity check on the binary. Returns 0 on success. */ - static int - check_binary_integrity (void) -@@ -665,25 +716,10 @@ check_binary_integrity (void) - err = gpg_error (GPG_ERR_INTERNAL); - else - { -- fname = xtrymalloc (strlen (libpath) + 1 + 5 + 1 ); -- if (!fname) -- err = gpg_error_from_syserror (); -- else -+ FILE *fp; -+ err = get_hmac_path(&fname); -+ if (!err) - { -- FILE *fp; -- char *p; -- -- /* Prefix the basename with a dot. */ -- strcpy (fname, libpath); -- p = strrchr (fname, '/'); -- if (p) -- p++; -- else -- p = fname; -- memmove (p+1, p, strlen (p)+1); -- *p = '.'; -- strcat (fname, ".hmac"); -- - /* Open the file. */ - fp = fopen (fname, "r"); - if (!fp) -@@ -734,6 +770,33 @@ check_binary_integrity (void) - #endif - } - -+int -+can_skip_selftests(void) -+{ -+ char *fname = NULL; -+ int ret = 0; -+ -+ if (fips_mode()) -+ return 0; -+ -+ if (get_hmac_path(&fname)) -+ return 0; -+ -+ /* check the hmac presence */ -+ if (access(fname, F_OK)) -+ /* no hmac file is present, don't run the tests */ -+ if (errno == ENOENT) -+ ret = 1; -+ /* otherwise one of these events happened: -+ * access() returned 0 -+ * -> run the tests -+ * some error other than ENOENT occurred -+ * -> run the tests anyway and let them fail -+ */ -+ -+ xfree(fname); -+ return ret; -+} - - /* Run the self-tests. If EXTENDED is true, extended versions of the - selftest are run, that is more tests than required by FIPS. */ -@@ -742,26 +805,13 @@ _gcry_fips_run_selftests (int extended) - { - enum module_states result = STATE_ERROR; - gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED; -- int in_poweron; -- -- lock_fsm (); -- in_poweron = (current_state == STATE_POWERON); -- unlock_fsm (); -- -- fips_new_state (STATE_SELFTEST); - -- /* We first check the integrity of the binary. -- If run from the constructor we are in POWERON state, -- we return and finish the remaining selftests before -- real use of the library. It will be in the POWERON -- state meanwhile. */ -- if (in_poweron) -- if (check_binary_integrity ()) -- goto leave; -- -- if (in_poweron) -+ if (can_skip_selftests()) - return 0; - -+ if (fips_mode ()) -+ fips_new_state (STATE_SELFTEST); -+ - if (run_cipher_selftests (extended)) - goto leave; - -@@ -774,6 +824,9 @@ _gcry_fips_run_selftests (int extended) - if (run_kdf_selftests (extended)) - goto leave; - -+ if (check_binary_integrity ()) -+ goto leave; -+ - /* Run random tests before the pubkey tests because the latter - require random. */ - if (run_random_selftests ()) -@@ -787,7 +840,8 @@ _gcry_fips_run_selftests (int extended) - ec = 0; - - leave: -- fips_new_state (result); -+ if (fips_mode ()) -+ fips_new_state (result); - - return ec; - } -@@ -843,7 +897,6 @@ fips_new_state (enum module_states new_s - { - case STATE_POWERON: - if (new_state == STATE_INIT -- || new_state == STATE_SELFTEST - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; -@@ -858,8 +911,6 @@ fips_new_state (enum module_states new_s - - case STATE_SELFTEST: - if (new_state == STATE_OPERATIONAL -- || new_state == STATE_INIT -- || new_state == STATE_SELFTEST - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; diff --git a/libgcrypt-indicate-shake.patch b/libgcrypt-indicate-shake.patch deleted file mode 100644 index bf2ece5..0000000 --- a/libgcrypt-indicate-shake.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: libgcrypt-1.9.4/src/fips.c -=================================================================== ---- libgcrypt-1.9.4.orig/src/fips.c -+++ libgcrypt-1.9.4/src/fips.c -@@ -593,6 +593,8 @@ _gcry_fips_indicator_hash (va_list arg_p - case GCRY_MD_SHA3_256: - case GCRY_MD_SHA3_384: - case GCRY_MD_SHA3_512: -+ case GCRY_MD_SHAKE128: -+ case GCRY_MD_SHAKE256: - return GPG_ERR_NO_ERROR; - default: - return GPG_ERR_NOT_SUPPORTED; diff --git a/libgcrypt-invoke-global_init-from-constructor.patch b/libgcrypt-invoke-global_init-from-constructor.patch deleted file mode 100644 index c733c3c..0000000 --- a/libgcrypt-invoke-global_init-from-constructor.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: libgcrypt-1.8.2/src/global.c -=================================================================== ---- libgcrypt-1.8.2.orig/src/global.c -+++ libgcrypt-1.8.2/src/global.c -@@ -145,6 +145,9 @@ void __attribute__ ((constructor)) _gcry - { - /* We always need the FSM lock to be functional. */ - _gcry_initialize_fsm_lock (); -+ -+ /* Run the self-tests from the constructor. */ -+ global_init (); - } - - /* This function is called by the macro fips_is_operational and makes diff --git a/libgcrypt-jitterentropy-3.3.0.patch b/libgcrypt-jitterentropy-3.3.0.patch deleted file mode 100644 index 65ebf25..0000000 --- a/libgcrypt-jitterentropy-3.3.0.patch +++ /dev/null @@ -1,4168 +0,0 @@ -Index: libgcrypt-1.9.4/LICENSES -=================================================================== ---- libgcrypt-1.9.4.orig/LICENSES -+++ libgcrypt-1.9.4/LICENSES -@@ -57,46 +57,53 @@ with any binary distributions derived fr - - For files: - - random/jitterentropy-base.c -+ - random/jitterentropy-gcd.c -+ - random/jitterentropy-gcd.h -+ - random/jitterentropy-health.c -+ - random/jitterentropy-health.h -+ - random/jitterentropy-noise.c -+ - random/jitterentropy-noise.h -+ - random/jitterentropy-sha3.c -+ - random/jitterentropy-sha3.h -+ - random/jitterentropy-timer.c -+ - random/jitterentropy-timer.h - - random/jitterentropy.h - - random/rndjent.c (plus common Libgcrypt copyright holders) - - #+begin_quote -- * Copyright Stephan Mueller , 2013 -- * -- * License -- * ======= -- * -- * 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 -- * the GNU General Public License, in which case the provisions of the GPL are -- * required INSTEAD OF the above restrictions. (This clause is -- * necessary due to a potential bad interaction between the GPL 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. -+ Copyright (C) 2017 - 2021, Stephan Mueller -+ -+ 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 -+ the GNU General Public License, in which case the provisions of the GPL2 -+ are required INSTEAD OF the above restrictions. (This clause is -+ necessary due to a potential bad interaction between the GPL 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. - #+end_quote - - For files: -Index: libgcrypt-1.9.4/random/jitterentropy-base.c -=================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-base.c -+++ libgcrypt-1.9.4/random/jitterentropy-base.c -@@ -11,29 +11,9 @@ - * Interface - * ========= - * -- * See documentation in doc/ folder. -- * -- * License -- * ======= -+ * See documentation in jitterentropy(3) man page. - * -- * 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 -- * the GNU General Public License, in which case the provisions of the GPL2 are -- * required INSTEAD OF the above restrictions. (This clause is -- * necessary due to a potential bad interaction between the GPL and -- * the restrictions contained in a BSD-style copyright.) -+ * License: see LICENSE file in root directory - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -@@ -49,30 +29,43 @@ - * DAMAGE. - */ - --#undef _FORTIFY_SOURCE --#ifdef __OPTIMIZE__ --#pragma GCC optimize ("O0") --#endif -- - #include "jitterentropy.h" - --#ifndef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -- /* only check optimization in a compilation for real work */ -- #ifdef __OPTIMIZE__ -- #error "The CPU Jitter random number generator must not be compiled with optimizations. See documentation. Use the compiler switch -O0 for compiling jitterentropy-base.c." -- #endif --#endif -+#include "jitterentropy-base.h" -+#include "jitterentropy-gcd.h" -+#include "jitterentropy-health.h" -+#include "jitterentropy-noise.h" -+#include "jitterentropy-timer.h" -+#include "jitterentropy-sha3.h" - --#define MAJVERSION 2 /* API / ABI incompatible changes, functional changes that -+#define MAJVERSION 3 /* API / ABI incompatible changes, functional changes that - * require consumer to be updated (as long as this number - * is zero, the API is not considered stable and can - * change without a bump of the major version) */ --#define MINVERSION 1 /* API compatible, ABI may change, functional -+#define MINVERSION 3 /* API compatible, ABI may change, functional - * enhancements only, consumer can be left unchanged if - * enhancements are not considered */ - #define PATCHLEVEL 0 /* API / ABI compatible, no functional changes, no - * enhancements, bug fixes only */ - -+/*************************************************************************** -+ * Jitter RNG Static Definitions -+ * -+ * None of the following should be altered -+ ***************************************************************************/ -+ -+#ifdef __OPTIMIZE__ -+ #error "The CPU Jitter random number generator must not be compiled with optimizations. See documentation. Use the compiler switch -O0 for compiling jitterentropy.c." -+#endif -+ -+/* -+ * JENT_POWERUP_TESTLOOPCOUNT needs some loops to identify edge -+ * systems. 100 is definitely too little. -+ * -+ * SP800-90B requires at least 1024 initial test cycles. -+ */ -+#define JENT_POWERUP_TESTLOOPCOUNT 1024 -+ - /** - * jent_version() - Return machine-usable version number of jent library - * -@@ -84,7 +77,7 @@ - * The result of this function can be used in comparing the version number - * in a calling program if version-specific calls need to be make. - * -- * Return: Version number of kcapi library -+ * @return Version number of jitterentropy library - */ - JENT_PRIVATE_STATIC - unsigned int jent_version(void) -@@ -98,414 +91,57 @@ unsigned int jent_version(void) - return version; - } - --/** -- * Update of the loop count used for the next round of -- * an entropy collection. -- * -- * Input: -- * @ec entropy collector struct -- may be NULL -- * @bits is the number of low bits of the timer to consider -- * @min is the number of bits we shift the timer value to the right at -- * the end to make sure we have a guaranteed minimum value -- * -- * @return Newly calculated loop counter -- */ --static uint64_t jent_loop_shuffle(struct rand_data *ec, -- unsigned int bits, unsigned int min) --{ -- uint64_t time = 0; -- uint64_t shuffle = 0; -- unsigned int i = 0; -- unsigned int mask = (1<data; -- /* -- * We fold the time value as much as possible to ensure that as many -- * bits of the time stamp are included as possible. -- */ -- for (i = 0; (DATA_SIZE_BITS / bits) > i; i++) { -- shuffle ^= time & mask; -- time = time >> bits; -- } -- -- /* -- * We add a lower boundary value to ensure we have a minimum -- * RNG loop count. -- */ -- return (shuffle + (1<data -- * -- * @return Number of loops the folding operation is performed -- */ --static uint64_t jent_lfsr_time(struct rand_data *ec, uint64_t time, -- uint64_t loop_cnt) -+/* Calculate log2 of given value assuming that the value is a power of 2 */ -+static inline unsigned int jent_log2_simple(unsigned int val) - { -- unsigned int i; -- uint64_t j = 0; -- uint64_t new = 0; --#define MAX_FOLD_LOOP_BIT 4 --#define MIN_FOLD_LOOP_BIT 0 -- uint64_t fold_loop_cnt = -- jent_loop_shuffle(ec, MAX_FOLD_LOOP_BIT, MIN_FOLD_LOOP_BIT); -- -- /* -- * testing purposes -- allow test app to set the counter, not -- * needed during runtime -- */ -- if (loop_cnt) -- fold_loop_cnt = loop_cnt; -- for (j = 0; j < fold_loop_cnt; j++) { -- new = ec->data; -- for (i = 1; (DATA_SIZE_BITS) >= i; i++) { -- uint64_t tmp = time << (DATA_SIZE_BITS - i); -- -- tmp = tmp >> (DATA_SIZE_BITS - 1); -+ unsigned int idx = 0; - -- /* -- * Fibonacci LSFR with polynomial of -- * x^64 + x^61 + x^56 + x^31 + x^28 + x^23 + 1 which is -- * primitive according to -- * http://poincare.matf.bg.ac.rs/~ezivkovm/publications/primpol1.pdf -- * (the shift values are the polynomial values minus one -- * due to counting bits from 0 to 63). As the current -- * position is always the LSB, the polynomial only needs -- * to shift data in from the left without wrap. -- */ -- new ^= tmp; -- new ^= ((new >> 63) & 1); -- new ^= ((new >> 60) & 1); -- new ^= ((new >> 55) & 1); -- new ^= ((new >> 30) & 1); -- new ^= ((new >> 27) & 1); -- new ^= ((new >> 22) & 1); -- new = rol64(new, 1); -- } -- } -- ec->data = new; -- -- return fold_loop_cnt; -+ while (val >>= 1) -+ idx++; -+ return idx; - } - --/** -- * Memory Access noise source -- this is a noise source based on variations in -- * memory access times -- * -- * This function performs memory accesses which will add to the timing -- * variations due to an unknown amount of CPU wait states that need to be -- * added when accessing memory. The memory size should be larger than the L1 -- * caches as outlined in the documentation and the associated testing. -- * -- * The L1 cache has a very high bandwidth, albeit its access rate is usually -- * slower than accessing CPU registers. Therefore, L1 accesses only add minimal -- * variations as the CPU has hardly to wait. Starting with L2, significant -- * variations are added because L2 typically does not belong to the CPU any more -- * and therefore a wider range of CPU wait states is necessary for accesses. -- * L3 and real memory accesses have even a wider range of wait states. However, -- * to reliably access either L3 or memory, the ec->mem memory must be quite -- * large which is usually not desirable. -- * -- * Input: -- * @ec Reference to the entropy collector with the memory access data -- if -- * the reference to the memory block to be accessed is NULL, this noise -- * source is disabled -- * @loop_cnt if a value not equal to 0 is set, use the given value as number of -- * loops to perform the folding -- * -- * @return Number of memory access operations -- */ --static unsigned int jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) -+/* Increase the memory size by one step */ -+static inline unsigned int jent_update_memsize(unsigned int flags) - { -- unsigned int wrap = 0; -- uint64_t i = 0; --#define MAX_ACC_LOOP_BIT 7 --#define MIN_ACC_LOOP_BIT 0 -- uint64_t acc_loop_cnt = -- jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT); -- -- if (NULL == ec || NULL == ec->mem) -- return 0; -- wrap = ec->memblocksize * ec->memblocks; -+ unsigned int global_max = JENT_FLAGS_TO_MAX_MEMSIZE( -+ JENT_MAX_MEMSIZE_MAX); -+ unsigned int max; - -- /* -- * testing purposes -- allow test app to set the counter, not -- * needed during runtime -- */ -- if (loop_cnt) -- acc_loop_cnt = loop_cnt; -+ max = JENT_FLAGS_TO_MAX_MEMSIZE(flags); - -- for (i = 0; i < (ec->memaccessloops + acc_loop_cnt); i++) { -- unsigned char *tmpval = ec->mem + ec->memlocation; -- /* -- * memory access: just add 1 to one byte, -- * wrap at 255 -- memory access implies read -- * from and write to memory location -- */ -- *tmpval = (*tmpval + 1) & 0xff; -+ if (!max) { - /* -- * Addition of memblocksize - 1 to pointer -- * with wrap around logic to ensure that every -- * memory location is hit evenly -+ * The safe starting value is the amount of memory we allocated -+ * last round. - */ -- ec->memlocation = ec->memlocation + ec->memblocksize - 1; -- ec->memlocation = ec->memlocation % wrap; -- } -- return i; -+ max = jent_log2_simple(JENT_MEMORY_SIZE); -+ /* Adjust offset */ -+ max = (max > JENT_MAX_MEMSIZE_OFFSET) ? -+ max - JENT_MAX_MEMSIZE_OFFSET : 0; -+ } else { -+ max++; -+ } -+ -+ max = (max > global_max) ? global_max : max; -+ -+ /* Clear out the max size */ -+ flags &= ~JENT_MAX_MEMSIZE_MASK; -+ /* Set the freshly calculated max size */ -+ flags |= JENT_MAX_MEMSIZE_TO_FLAGS(max); -+ -+ return flags; - } - - /*************************************************************************** -- * Start of entropy processing logic -+ * Random Number Generation - ***************************************************************************/ - - /** -- * Stuck test by checking the: -- * 1st derivation of the jitter measurement (time delta) -- * 2nd derivation of the jitter measurement (delta of time deltas) -- * 3rd derivation of the jitter measurement (delta of delta of time deltas) -- * -- * All values must always be non-zero. -- * -- * Input: -- * @ec Reference to entropy collector -- * @current_delta Jitter time delta -- * -- * @return -- * 0 jitter measurement not stuck (good bit) -- * 1 jitter measurement stuck (reject bit) -- */ --static int jent_stuck(struct rand_data *ec, uint64_t current_delta) --{ -- int64_t delta2 = ec->last_delta - current_delta; -- int64_t delta3 = (uint64_t)delta2 - (uint64_t)ec->last_delta2; -- -- ec->last_delta = current_delta; -- ec->last_delta2 = delta2; -- -- if (!current_delta || !delta2 || !delta3) -- return 1; -- -- return 0; --} -- --/** -- * This is the heart of the entropy generation: calculate time deltas and -- * use the CPU jitter in the time deltas. The jitter is injected into the -- * entropy pool. -- * -- * WARNING: ensure that ->prev_time is primed before using the output -- * of this function! This can be done by calling this function -- * and not using its result. -- * -- * Input: -- * @entropy_collector Reference to entropy collector -- * -- * @return: result of stuck test -- */ --static int jent_measure_jitter(struct rand_data *ec) --{ -- uint64_t time = 0; -- uint64_t current_delta = 0; -- int stuck; -- -- /* Invoke one noise source before time measurement to add variations */ -- jent_memaccess(ec, 0); -- -- /* -- * Get time stamp and calculate time delta to previous -- * invocation to measure the timing variations -- */ -- jent_get_nstime(&time); -- current_delta = time - ec->prev_time; -- ec->prev_time = time; -- -- /* Now call the next noise sources which also injects the data */ -- jent_lfsr_time(ec, current_delta, 0); -- -- /* Check whether we have a stuck measurement. */ -- stuck = jent_stuck(ec, current_delta); -- -- /* -- * Rotate the data buffer by a prime number (any odd number would -- * do) to ensure that every bit position of the input time stamp -- * has an even chance of being merged with a bit position in the -- * entropy pool. We do not use one here as the adjacent bits in -- * successive time deltas may have some form of dependency. The -- * chosen value of 7 implies that the low 7 bits of the next -- * time delta value is concatenated with the current time delta. -- */ -- if (!stuck) -- ec->data = rol64(ec->data, 7); -- -- return stuck; --} -- --/** -- * Shuffle the pool a bit by mixing some value with a bijective function (XOR) -- * into the pool. -- * -- * The function generates a mixer value that depends on the bits set and the -- * location of the set bits in the random number generated by the entropy -- * source. Therefore, based on the generated random number, this mixer value -- * can have 2**64 different values. That mixer value is initialized with the -- * first two SHA-1 constants. After obtaining the mixer value, it is XORed into -- * the random number. -- * -- * The mixer value is not assumed to contain any entropy. But due to the XOR -- * operation, it can also not destroy any entropy present in the entropy pool. -- * -- * Input: -- * @entropy_collector Reference to entropy collector -- */ --static void jent_stir_pool(struct rand_data *entropy_collector) --{ -- /* -- * to shut up GCC on 32 bit, we have to initialize the 64 variable -- * with two 32 bit variables -- */ -- union c { -- uint64_t uint64; -- uint32_t uint32[2]; -- }; -- /* -- * This constant is derived from the first two 32 bit initialization -- * vectors of SHA-1 as defined in FIPS 180-4 section 5.3.1 -- */ -- union c constant; -- /* -- * The start value of the mixer variable is derived from the third -- * and fourth 32 bit initialization vector of SHA-1 as defined in -- * FIPS 180-4 section 5.3.1 -- */ -- union c mixer; -- unsigned int i = 0; -- -- /* Ensure that the function implements a constant time operation. */ -- union c throw_away; -- -- /* -- * Store the SHA-1 constants in reverse order to make up the 64 bit -- * value -- this applies to a little endian system, on a big endian -- * system, it reverses as expected. But this really does not matter -- * as we do not rely on the specific numbers. We just pick the SHA-1 -- * constants as they have a good mix of bit set and unset. -- */ -- constant.uint32[1] = 0x67452301; -- constant.uint32[0] = 0xefcdab89; -- mixer.uint32[1] = 0x98badcfe; -- mixer.uint32[0] = 0x10325476; -- -- for (i = 0; i < DATA_SIZE_BITS; i++) { -- /* -- * get the i-th bit of the input random number and only XOR -- * the constant into the mixer value when that bit is set -- */ -- if ((entropy_collector->data >> i) & 1) -- mixer.uint64 ^= constant.uint64; -- else -- throw_away.uint64 ^= constant.uint64; -- mixer.uint64 = rol64(mixer.uint64, 1); -- } -- entropy_collector->data ^= mixer.uint64; --} -- --/** -- * Generator of one 64 bit random number -- * Function fills rand_data->data -- * -- * Input: -- * @ec Reference to entropy collector -- */ --static void jent_gen_entropy(struct rand_data *ec) --{ -- unsigned int k = 0; -- -- /* priming of the ->prev_time value */ -- jent_measure_jitter(ec); -- -- while (1) { -- /* If a stuck measurement is received, repeat measurement */ -- if (jent_measure_jitter(ec)) -- continue; -- -- /* -- * We multiply the loop value with ->osr to obtain the -- * oversampling rate requested by the caller -- */ -- if (++k >= (DATA_SIZE_BITS * ec->osr)) -- break; -- } -- if (ec->stir) -- jent_stir_pool(ec); --} -- --/** -- * The continuous test required by FIPS 140-2 -- the function automatically -- * primes the test if needed. -- * -- * Return: -- * 0 if FIPS test passed -- * < 0 if FIPS test failed -- */ --static int jent_fips_test(struct rand_data *ec) --{ -- if (ec->fips_enabled == -1) -- return 0; -- -- if (ec->fips_enabled == 0) { -- if (!jent_fips_enabled()) { -- ec->fips_enabled = -1; -- return 0; -- } else -- ec->fips_enabled = 1; -- } -- -- /* prime the FIPS test */ -- if (!ec->old_data) { -- ec->old_data = ec->data; -- jent_gen_entropy(ec); -- } -- -- if (ec->data == ec->old_data) -- return -1; -- -- ec->old_data = ec->data; -- -- return 0; --} -- --/** - * Entry function: Obtain entropy for the caller. - * - * This function invokes the entropy gathering logic as often to generate -@@ -515,34 +151,50 @@ static int jent_fips_test(struct rand_da - * This function truncates the last 64 bit entropy value output to the exact - * size specified by the caller. - * -- * Input: -- * @ec Reference to entropy collector -- * @data pointer to buffer for storing random data -- buffer must already -- * exist -- * @len size of the buffer, specifying also the requested number of random -- * in bytes -+ * @ec [in] Reference to entropy collector -+ * @data [out] pointer to buffer for storing random data -- buffer must -+ * already exist -+ * @len [in] size of the buffer, specifying also the requested number of random -+ * in bytes - * - * @return number of bytes returned when request is fulfilled or an error - * - * The following error codes can occur: - * -1 entropy_collector is NULL -- * -2 FIPS test failed -+ * -2 RCT failed -+ * -3 APT test failed -+ * -4 The timer cannot be initialized -+ * -5 LAG failure - */ - JENT_PRIVATE_STATIC - ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len) - { - char *p = data; - size_t orig_len = len; -+ int ret = 0; - - if (NULL == ec) - return -1; - -- while (0 < len) { -+ if (jent_notime_settick(ec)) -+ return -4; -+ -+ while (len > 0) { - size_t tocopy; -+ unsigned int health_test_result; - -- jent_gen_entropy(ec); -- if (jent_fips_test(ec)) -- return -2; -+ jent_random_data(ec); -+ -+ if ((health_test_result = jent_health_failure(ec))) { -+ if (health_test_result & JENT_RCT_FAILURE) -+ ret = -2; -+ else if (health_test_result & JENT_APT_FAILURE) -+ ret = -3; -+ else -+ ret = -5; -+ -+ goto err; -+ } - - if ((DATA_SIZE_BITS / 8) < len) - tocopy = (DATA_SIZE_BITS / 8); -@@ -569,93 +221,349 @@ ssize_t jent_read_entropy(struct rand_da - * memory protects the entropy pool. Moreover, note that using this - * call reduces the speed of the RNG by up to half - */ --#ifndef CONFIG_CRYPTO_CPU_JITTERENTROPY_SECURE_MEMORY -- jent_gen_entropy(ec); -+#ifndef JENT_CPU_JITTERENTROPY_SECURE_MEMORY -+ jent_random_data(ec); - #endif -- return orig_len; -+ -+err: -+ jent_notime_unsettick(ec); -+ return ret ? ret : (ssize_t)orig_len; -+} -+ -+static struct rand_data *_jent_entropy_collector_alloc(unsigned int osr, -+ unsigned int flags); -+ -+/** -+ * Entry function: Obtain entropy for the caller. -+ * -+ * This is a service function to jent_read_entropy() with the difference -+ * that it automatically re-allocates the entropy collector if a health -+ * test failure is observed. Before reallocation, a new power-on health test -+ * is performed. The allocation of the new entropy collector automatically -+ * increases the OSR by one. This is done based on the idea that a health -+ * test failure indicates that the assumed entropy rate is too high. -+ * -+ * Note the function returns with an health test error if the OSR is -+ * getting too large. If an error is returned by this function, the Jitter RNG -+ * is not safe to be used on the current system. -+ * -+ * @ec [in] Reference to entropy collector - this is a double pointer as -+ * The entropy collector may be freed and reallocated. -+ * @data [out] pointer to buffer for storing random data -- buffer must -+ * already exist -+ * @len [in] size of the buffer, specifying also the requested number of random -+ * in bytes -+ * -+ * @return see jent_read_entropy() -+ */ -+JENT_PRIVATE_STATIC -+ssize_t jent_read_entropy_safe(struct rand_data **ec, char *data, size_t len) -+{ -+ char *p = data; -+ size_t orig_len = len; -+ ssize_t ret = 0; -+ -+ if (!ec) -+ return -1; -+ -+ while (len > 0) { -+ unsigned int osr, flags, max_mem_set; -+ -+ ret = jent_read_entropy(*ec, p, len); -+ -+ switch (ret) { -+ case -1: -+ case -4: -+ return ret; -+ case -2: -+ case -3: -+ case -5: -+ osr = (*ec)->osr + 1; -+ flags = (*ec)->flags; -+ max_mem_set = (*ec)->max_mem_set; -+ -+ /* generic arbitrary cutoff */ -+ if (osr > 20) -+ return ret; -+ -+ /* -+ * If the caller did not set any specific maximum value -+ * let the Jitter RNG increase the maximum memory by -+ * one step. -+ */ -+ if (!max_mem_set) -+ flags = jent_update_memsize(flags); -+ -+ /* -+ * re-allocate entropy collector with higher OSR and -+ * memory size -+ */ -+ jent_entropy_collector_free(*ec); -+ -+ /* Perform new health test with updated OSR */ -+ if (jent_entropy_init_ex(osr, flags)) -+ return -1; -+ -+ *ec = _jent_entropy_collector_alloc(osr, flags); -+ if (!*ec) -+ return -1; -+ -+ /* Remember whether caller configured memory size */ -+ (*ec)->max_mem_set = !!max_mem_set; -+ -+ break; -+ -+ default: -+ len -= (size_t)ret; -+ p += (size_t)ret; -+ } -+ } -+ -+ return (ssize_t)orig_len; - } - - /*************************************************************************** - * Initialization logic - ***************************************************************************/ - --JENT_PRIVATE_STATIC --struct rand_data *jent_entropy_collector_alloc(unsigned int osr, -- unsigned int flags) -+/* -+ * Obtain memory size to allocate for memory access variations. -+ * -+ * The maximum variations we can get from the memory access is when we allocate -+ * a bit more memory than we have as data cache. But allocating as much -+ * memory as we have as data cache might strain the resources on the system -+ * more than necessary. -+ * -+ * On a lot of systems it is not necessary to need so much memory as the -+ * variations coming from the general Jitter RNG execution commonly provide -+ * large amount of variations. -+ * -+ * Thus, the default is: -+ * -+ * min(JENT_MEMORY_SIZE, data cache size) -+ * -+ * In case the data cache size cannot be obtained, use JENT_MEMORY_SIZE. -+ * -+ * If the caller provides a maximum memory size, use -+ * min(provided max memory, data cache size). -+ */ -+static inline uint32_t jent_memsize(unsigned int flags) -+{ -+ uint32_t memsize, max_memsize; -+ -+ max_memsize = JENT_FLAGS_TO_MAX_MEMSIZE(flags); -+ -+ if (max_memsize == 0) { -+ max_memsize = JENT_MEMORY_SIZE; -+ } else { -+ max_memsize = UINT32_C(1) << (max_memsize + -+ JENT_MAX_MEMSIZE_OFFSET); -+ } -+ -+ /* Allocate memory for adding variations based on memory access */ -+ memsize = jent_cache_size_roundup(); -+ -+ /* Limit the memory as defined by caller */ -+ memsize = (memsize > max_memsize) ? max_memsize : memsize; -+ -+ /* Set a value if none was found */ -+ if (!memsize) -+ memsize = JENT_MEMORY_SIZE; -+ -+ return memsize; -+} -+ -+static int jent_selftest_run = 0; -+ -+static struct rand_data -+*jent_entropy_collector_alloc_internal(unsigned int osr, unsigned int flags) - { - struct rand_data *entropy_collector; - -+ /* -+ * Requesting disabling and forcing of internal timer -+ * makes no sense. -+ */ -+ if ((flags & JENT_DISABLE_INTERNAL_TIMER) && -+ (flags & JENT_FORCE_INTERNAL_TIMER)) -+ return NULL; -+ -+ /* Force the self test to be run */ -+ if (!jent_selftest_run && jent_entropy_init_ex(osr, flags)) -+ return NULL; -+ -+ /* -+ * If the initial test code concludes to force the internal timer -+ * and the user requests it not to be used, do not allocate -+ * the Jitter RNG instance. -+ */ -+ if (jent_notime_forced() && (flags & JENT_DISABLE_INTERNAL_TIMER)) -+ return NULL; -+ - entropy_collector = jent_zalloc(sizeof(struct rand_data)); - if (NULL == entropy_collector) - return NULL; - - if (!(flags & JENT_DISABLE_MEMORY_ACCESS)) { -- /* Allocate memory for adding variations based on memory -- * access -+ uint32_t memsize = jent_memsize(flags); -+ -+ entropy_collector->mem = _gcry_calloc (1, memsize); -+ -+#ifdef JENT_RANDOM_MEMACCESS -+ /* -+ * Transform the size into a mask - it is assumed that size is -+ * a power of 2. - */ -- entropy_collector->mem = -- (unsigned char *)jent_zalloc(JENT_MEMORY_SIZE); -- if (NULL == entropy_collector->mem) { -- jent_zfree(entropy_collector, sizeof(struct rand_data)); -- return NULL; -- } -- entropy_collector->memblocksize = JENT_MEMORY_BLOCKSIZE; -+ entropy_collector->memmask = memsize - 1; -+#else /* JENT_RANDOM_MEMACCESS */ -+ entropy_collector->memblocksize = memsize / JENT_MEMORY_BLOCKS; - entropy_collector->memblocks = JENT_MEMORY_BLOCKS; -+ -+ /* sanity check */ -+ if (entropy_collector->memblocksize * -+ entropy_collector->memblocks != memsize) -+ goto err; -+ -+#endif /* JENT_RANDOM_MEMACCESS */ -+ -+ if (entropy_collector->mem == NULL) -+ goto err; - entropy_collector->memaccessloops = JENT_MEMORY_ACCESSLOOPS; - } - - /* verify and set the oversampling rate */ -- if (0 == osr) -- osr = 1; /* minimum sampling rate is 1 */ -+ if (osr < JENT_MIN_OSR) -+ osr = JENT_MIN_OSR; - entropy_collector->osr = osr; -+ entropy_collector->flags = flags; - -- entropy_collector->stir = 1; -- if (flags & JENT_DISABLE_STIR) -- entropy_collector->stir = 0; -- if (flags & JENT_DISABLE_UNBIAS) -- entropy_collector->disable_unbias = 1; -+ if (jent_fips_enabled() || (flags & JENT_FORCE_FIPS)) -+ entropy_collector->fips_enabled = 1; - -- /* fill the data pad with non-zero values */ -- jent_gen_entropy(entropy_collector); -+ /* Initialize the APT */ -+ jent_apt_init(entropy_collector, osr); -+ -+ /* Initialize the Lag Predictor Test */ -+ jent_lag_init(entropy_collector, osr); -+ -+ /* Was jent_entropy_init run (establishing the common GCD)? */ -+ if (jent_gcd_get(&entropy_collector->jent_common_timer_gcd)) { -+ /* -+ * It was not. This should probably be an error, but this -+ * behavior breaks the test code. Set the gcd to a value that -+ * won't hurt anything. -+ */ -+ entropy_collector->jent_common_timer_gcd = 1; -+ } -+ -+ /* -+ * Use timer-less noise source - note, OSR must be set in -+ * entropy_collector! -+ */ -+ if (!(flags & JENT_DISABLE_INTERNAL_TIMER)) { -+ if (jent_notime_enable(entropy_collector, flags)) -+ goto err; -+ } - - return entropy_collector; -+ -+err: -+ if (entropy_collector->mem != NULL) -+ jent_zfree(entropy_collector->mem, JENT_MEMORY_SIZE); -+ jent_zfree(entropy_collector, sizeof(struct rand_data)); -+ return NULL; -+} -+ -+static struct rand_data *_jent_entropy_collector_alloc(unsigned int osr, -+ unsigned int flags) -+{ -+ struct rand_data *ec = jent_entropy_collector_alloc_internal(osr, -+ flags); -+ -+ if (!ec) -+ return ec; -+ -+ /* fill the data pad with non-zero values */ -+ if (jent_notime_settick(ec)) { -+ jent_entropy_collector_free(ec); -+ return NULL; -+ } -+ jent_random_data(ec); -+ jent_notime_unsettick(ec); -+ -+ return ec; -+} -+ -+JENT_PRIVATE_STATIC -+struct rand_data *jent_entropy_collector_alloc(unsigned int osr, -+ unsigned int flags) -+{ -+ struct rand_data *ec = _jent_entropy_collector_alloc(osr, flags); -+ -+ /* Remember that the caller provided a maximum size flag */ -+ if (ec) -+ ec->max_mem_set = !!JENT_FLAGS_TO_MAX_MEMSIZE(flags); -+ -+ return ec; - } - - JENT_PRIVATE_STATIC - void jent_entropy_collector_free(struct rand_data *entropy_collector) - { -- if (NULL != entropy_collector) { -- if (NULL != entropy_collector->mem) { -- jent_zfree(entropy_collector->mem, JENT_MEMORY_SIZE); -+ if (entropy_collector != NULL) { -+ jent_notime_disable(entropy_collector); -+ if (entropy_collector->mem != NULL) { -+ jent_zfree(entropy_collector->mem, -+ jent_memsize(entropy_collector->flags)); - entropy_collector->mem = NULL; - } - jent_zfree(entropy_collector, sizeof(struct rand_data)); - } - } - --JENT_PRIVATE_STATIC --int jent_entropy_init(void) -+int jent_time_entropy_init(unsigned int osr, unsigned int flags) - { -- int i; -- uint64_t delta_sum = 0; -- uint64_t old_delta = 0; -- int time_backwards = 0; -- int count_mod = 0; -- int count_stuck = 0; -- struct rand_data ec; -+ struct rand_data *ec; -+ uint64_t *delta_history; -+ int i, time_backwards = 0, count_stuck = 0, ret = 0; -+ unsigned int health_test_result; - -- memset(&ec, 0, sizeof(ec)); -+ delta_history = jent_gcd_init(JENT_POWERUP_TESTLOOPCOUNT); -+ if (!delta_history) -+ return EMEM; -+ -+ if (flags & JENT_FORCE_INTERNAL_TIMER) -+ jent_notime_force(); -+ else -+ flags |= JENT_DISABLE_INTERNAL_TIMER; -+ -+ /* -+ * If the start-up health tests (including the APT and RCT) are not -+ * run, then the entropy source is not 90B compliant. We could test if -+ * fips_enabled should be set using the jent_fips_enabled() function, -+ * but this can be overridden using the JENT_FORCE_FIPS flag, which -+ * isn't passed in yet. It is better to run the tests on the small -+ * amount of data that we have, which should not fail unless things -+ * are really bad. -+ */ -+ flags |= JENT_FORCE_FIPS; -+ ec = jent_entropy_collector_alloc_internal(osr, flags); -+ if (!ec) { -+ ret = EMEM; -+ goto out; -+ } -+ -+ if (jent_notime_settick(ec)) { -+ ret = EMEM; -+ goto out; -+ } -+ -+ /* To initialize the prior time. */ -+ jent_measure_jitter(ec, 0, NULL); - - /* We could perform statistical tests here, but the problem is - * that we only have a few loop counts to do testing. These -- * loop counts may show some slight skew and we produce -- * false positives. -- * -- * Moreover, only old systems show potentially problematic -- * jitter entropy that could potentially be caught here. But -- * the RNG is intended for hardware that is available or widely -- * used, but not old systems that are long out of favor. Thus, -- * no statistical tests. -+ * loop counts may show some slight skew leading to false positives. - */ - - /* -@@ -664,38 +572,31 @@ int jent_entropy_init(void) - * following sanity checks verify that we have a high-resolution - * timer. - */ -- /* -- * TESTLOOPCOUNT needs some loops to identify edge systems. 100 is -- * definitely too little. -- */ --#define TESTLOOPCOUNT 300 - #define CLEARCACHE 100 -- for (i = 0; (TESTLOOPCOUNT + CLEARCACHE) > i; i++) { -- uint64_t time = 0; -- uint64_t time2 = 0; -- uint64_t delta = 0; -- unsigned int lowdelta = 0; -- int stuck; -+ for (i = -CLEARCACHE; i < JENT_POWERUP_TESTLOOPCOUNT; i++) { -+ uint64_t start_time = 0, end_time = 0, delta = 0; -+ unsigned int stuck; - - /* Invoke core entropy collection logic */ -- jent_get_nstime(&time); -- ec.prev_time = time; -- jent_lfsr_time(&ec, time, 0); -- jent_get_nstime(&time2); -+ stuck = jent_measure_jitter(ec, 0, &delta); -+ end_time = ec->prev_time; -+ start_time = ec->prev_time - delta; - - /* test whether timer works */ -- if (!time || !time2) -- return ENOTIME; -- delta = time2 - time; -+ if (!start_time || !end_time) { -+ ret = ENOTIME; -+ goto out; -+ } -+ - /* - * test whether timer is fine grained enough to provide - * delta even when called shortly after each other -- this - * implies that we also have a high resolution timer - */ -- if (!delta) -- return ECOARSETIME; -- -- stuck = jent_stuck(&ec, delta); -+ if (!delta || (end_time == start_time)) { -+ ret = ECOARSETIME; -+ goto out; -+ } - - /* - * up to here we did not modify any variable that will be -@@ -704,32 +605,18 @@ int jent_entropy_init(void) - * etc. with the goal to clear it to get the worst case - * measurements. - */ -- if (CLEARCACHE > i) -+ if (i < 0) - continue; - - if (stuck) - count_stuck++; - - /* test whether we have an increasing timer */ -- if (!(time2 > time)) -+ if (!(end_time > start_time)) - time_backwards++; - -- /* use 32 bit value to ensure compilation on 32 bit arches */ -- lowdelta = time2 - time; -- if (!(lowdelta % 100)) -- count_mod++; -- -- /* -- * ensure that we have a varying delta timer which is necessary -- * for the calculation of entropy -- perform this check -- * only after the first loop is executed as we need to prime -- * the old_data value -- */ -- if (delta > old_delta) -- delta_sum += (delta - old_delta); -- else -- delta_sum += (old_delta - delta); -- old_delta = delta; -+ /* Watch for common adjacent GCD values */ -+ jent_gcd_add_value(delta_history, delta, i); - } - - /* -@@ -739,55 +626,109 @@ int jent_entropy_init(void) - * should not fail. The value of 3 should cover the NTP case being - * performed during our test run. - */ -- if (3 < time_backwards) -- return ENOMONOTONIC; -+ if (time_backwards > 3) { -+ ret = ENOMONOTONIC; -+ goto out; -+ } - -- /* -- * Variations of deltas of time must on average be larger -- * than 1 to ensure the entropy estimation -- * implied with 1 is preserved -- */ -- if ((delta_sum) <= 1) -- return EMINVARVAR; -+ /* First, did we encounter a health test failure? */ -+ if ((health_test_result = jent_health_failure(ec))) { -+ ret = (health_test_result & JENT_RCT_FAILURE) ? ERCT : EHEALTH; -+ goto out; -+ } - -- /* -- * Ensure that we have variations in the time stamp below 10 for at least -- * 10% of all checks -- on some platforms, the counter increments in -- * multiples of 100, but not always -- */ -- if ((TESTLOOPCOUNT/10 * 9) < count_mod) -- return ECOARSETIME; -+ ret = jent_gcd_analyze(delta_history, JENT_POWERUP_TESTLOOPCOUNT); -+ if (ret) -+ goto out; - - /* - * If we have more than 90% stuck results, then this Jitter RNG is - * likely to not work well. - */ -- if (JENT_STUCK_INIT_THRES(TESTLOOPCOUNT) < count_stuck) -- return ESTUCK; -+ if (JENT_STUCK_INIT_THRES(JENT_POWERUP_TESTLOOPCOUNT) < count_stuck) -+ ret = ESTUCK; -+ -+out: -+ jent_gcd_fini(delta_history, JENT_POWERUP_TESTLOOPCOUNT); -+ -+ if ((flags & JENT_FORCE_INTERNAL_TIMER) && ec) -+ jent_notime_unsettick(ec); -+ -+ jent_entropy_collector_free(ec); - -- return 0; -+ return ret; - } - --/*************************************************************************** -- * Statistical test logic not compiled for regular operation -- ***************************************************************************/ -+static inline int jent_entropy_init_common_pre(void) -+{ -+ int ret; -+ -+ jent_notime_block_switch(); -+ -+ if (sha3_tester()) -+ return EHASH; -+ -+ ret = jent_gcd_selftest(); -+ -+ jent_selftest_run = 1; -+ -+ return ret; -+} -+ -+static inline int jent_entropy_init_common_post(int ret) -+{ -+ /* Unmark the execution of the self tests if they failed. */ -+ if (ret) -+ jent_selftest_run = 0; -+ -+ return ret; -+} -+ -+JENT_PRIVATE_STATIC -+int jent_entropy_init(void) -+{ -+ int ret = jent_entropy_init_common_pre(); -+ -+ if (ret) -+ return ret; -+ -+ ret = jent_time_entropy_init(0, JENT_DISABLE_INTERNAL_TIMER); -+ -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+ if (ret) -+ ret = jent_time_entropy_init(0, JENT_FORCE_INTERNAL_TIMER); -+#endif /* JENT_CONF_ENABLE_INTERNAL_TIMER */ -+ -+ return jent_entropy_init_common_post(ret); -+} - --#ifdef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT --/* -- * Statistical test: return the time duration for the folding operation. If min -- * is set, perform the given number of LFSR ops. Otherwise, allow the -- * loop count shuffling to define the number of LFSR ops. -- */ - JENT_PRIVATE_STATIC --uint64_t jent_lfsr_var_stat(struct rand_data *ec, unsigned int min) -+int jent_entropy_init_ex(unsigned int osr, unsigned int flags) - { -- uint64_t time = 0; -- uint64_t time2 = 0; -+ int ret = jent_entropy_init_common_pre(); -+ -+ if (ret) -+ return ret; -+ -+ /* Test without internal timer unless caller does not want it */ -+ if (!(flags & JENT_FORCE_INTERNAL_TIMER)) -+ ret = jent_time_entropy_init(osr, -+ flags | JENT_DISABLE_INTERNAL_TIMER); - -- jent_get_nstime(&time); -- jent_memaccess(ec, min); -- jent_lfsr_time(ec, time, min); -- jent_get_nstime(&time2); -- return ((time2 - time)); -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+ /* Test with internal timer unless caller does not want it */ -+ if (ret && !(flags & JENT_DISABLE_INTERNAL_TIMER)) -+ ret = jent_time_entropy_init(osr, -+ flags | JENT_FORCE_INTERNAL_TIMER); -+#endif /* JENT_CONF_ENABLE_INTERNAL_TIMER */ -+ -+ return jent_entropy_init_common_post(ret); - } --#endif /* CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT */ -+ -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+JENT_PRIVATE_STATIC -+int jent_entropy_switch_notime_impl(struct jent_notime_thread *new_thread) -+{ -+ return jent_notime_switch(new_thread); -+} -+#endif -Index: libgcrypt-1.9.4/random/jitterentropy-base.h -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-base.h -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#ifndef JITTERENTROPY_BASE_H -+#define JITTERENTROPY_BASE_H -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+int jent_time_entropy_init(unsigned int osr, unsigned int flags); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* JITTERENTROPY_BASE_H */ -Index: libgcrypt-1.9.4/random/jitterentropy-base-user.h -=================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-base-user.h -+++ libgcrypt-1.9.4/random/jitterentropy-base-user.h -@@ -39,6 +39,9 @@ - * DAMAGE. - */ - -+#include -+#include -+ - #ifndef GCRYPT_JITTERENTROPY_BASE_USER_H - #define GCRYPT_JITTERENTROPY_BASE_USER_H - -@@ -131,4 +134,174 @@ jent_fips_enabled(void) - } - - -+static inline void jent_memset_secure(void *s, size_t n) -+{ -+ wipememory (s, n); -+} -+ -+static inline long jent_ncpu(void) -+{ -+#ifdef _POSIX_SOURCE -+ long ncpu = sysconf(_SC_NPROCESSORS_ONLN); -+ -+ if (ncpu == -1) -+ return -errno; -+ -+ if (ncpu == 0) -+ return -EFAULT; -+ -+ return ncpu; -+#else -+ return 1; -+#endif -+} -+ -+#ifdef __linux__ -+ -+# if defined(_SC_LEVEL1_DCACHE_SIZE) && \ -+ defined(_SC_LEVEL2_CACHE_SIZE) && \ -+ defined(_SC_LEVEL3_CACHE_SIZE) -+ -+static inline void jent_get_cachesize(long *l1, long *l2, long *l3) -+{ -+ *l1 = sysconf(_SC_LEVEL1_DCACHE_SIZE); -+ *l2 = sysconf(_SC_LEVEL2_CACHE_SIZE); -+ *l3 = sysconf(_SC_LEVEL3_CACHE_SIZE); -+} -+ -+# else -+ -+static inline void jent_get_cachesize(long *l1, long *l2, long *l3) -+{ -+#define JENT_SYSFS_CACHE_DIR "/sys/devices/system/cpu/cpu0/cache" -+ long val; -+ unsigned int i; -+ char buf[10], file[50]; -+ int fd = 0; -+ -+ /* Iterate over all caches */ -+ for (i = 0; i < 4; i++) { -+ unsigned int shift = 0; -+ char *ext; -+ -+ /* -+ * Check the cache type - we are only interested in Unified -+ * and Data caches. -+ */ -+ memset(buf, 0, sizeof(buf)); -+ snprintf(file, sizeof(file), "%s/index%u/type", -+ JENT_SYSFS_CACHE_DIR, i); -+ fd = open(file, O_RDONLY); -+ if (fd < 0) -+ continue; -+ while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR); -+ close(fd); -+ buf[sizeof(buf) - 1] = '\0'; -+ -+ if (strncmp(buf, "Data", 4) && strncmp(buf, "Unified", 7)) -+ continue; -+ -+ /* Get size of cache */ -+ memset(buf, 0, sizeof(buf)); -+ snprintf(file, sizeof(file), "%s/index%u/size", -+ JENT_SYSFS_CACHE_DIR, i); -+ -+ fd = open(file, O_RDONLY); -+ if (fd < 0) -+ continue; -+ while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR); -+ close(fd); -+ buf[sizeof(buf) - 1] = '\0'; -+ -+ ext = strstr(buf, "K"); -+ if (ext) { -+ shift = 10; -+ ext = '\0'; -+ } else { -+ ext = strstr(buf, "M"); -+ if (ext) { -+ shift = 20; -+ ext = '\0'; -+ } -+ } -+ -+ val = strtol(buf, NULL, 10); -+ if (val == LONG_MAX) -+ continue; -+ val <<= shift; -+ -+ if (!*l1) -+ *l1 = val; -+ else if (!*l2) -+ *l2 = val; -+ else { -+ *l3 = val; -+ break; -+ } -+ } -+#undef JENT_SYSFS_CACHE_DIR -+} -+ -+# endif -+ -+static inline uint32_t jent_cache_size_roundup(void) -+{ -+ static int checked = 0; -+ static uint32_t cache_size = 0; -+ -+ if (!checked) { -+ long l1 = 0, l2 = 0, l3 = 0; -+ -+ jent_get_cachesize(&l1, &l2, &l3); -+ checked = 1; -+ -+ /* Cache size reported by system */ -+ if (l1 > 0) -+ cache_size += (uint32_t)l1; -+ if (l2 > 0) -+ cache_size += (uint32_t)l2; -+ if (l3 > 0) -+ cache_size += (uint32_t)l3; -+ -+ /* -+ * Force the output_size to be of the form -+ * (bounding_power_of_2 - 1). -+ */ -+ cache_size |= (cache_size >> 1); -+ cache_size |= (cache_size >> 2); -+ cache_size |= (cache_size >> 4); -+ cache_size |= (cache_size >> 8); -+ cache_size |= (cache_size >> 16); -+ -+ if (cache_size == 0) -+ return 0; -+ -+ /* -+ * Make the output_size the smallest power of 2 strictly -+ * greater than cache_size. -+ */ -+ cache_size++; -+ } -+ -+ return cache_size; -+} -+ -+#else /* __linux__ */ -+ -+static inline uint32_t jent_cache_size_roundup(void) -+{ -+ return 0; -+} -+ -+#endif /* __linux__ */ -+ -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+#include -+ -+static inline void jent_yield(void) -+{ -+ sched_yield(); -+} -+#endif -+ - #endif /* GCRYPT_JITTERENTROPY_BASE_USER_H */ -Index: libgcrypt-1.9.4/random/jitterentropy-gcd.c -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-gcd.c -@@ -0,0 +1,188 @@ -+/* Jitter RNG: GCD health test -+ * -+ * Copyright (C) 2021, Joshua E. Hill -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#include "jitterentropy.h" -+#include "jitterentropy-gcd.h" -+ -+/* The common divisor for all timestamp deltas */ -+static uint64_t jent_common_timer_gcd = 0; -+ -+static inline int jent_gcd_tested(void) -+{ -+ return (jent_common_timer_gcd != 0); -+} -+ -+/* A straight forward implementation of the Euclidean algorithm for GCD. */ -+static inline uint64_t jent_gcd64(uint64_t a, uint64_t b) -+{ -+ /* Make a greater a than or equal b. */ -+ if (a < b) { -+ uint64_t c = a; -+ a = b; -+ b = c; -+ } -+ -+ /* Now perform the standard inner-loop for this algorithm.*/ -+ while (b != 0) { -+ uint64_t r; -+ -+ r = a % b; -+ -+ a = b; -+ b = r; -+ } -+ -+ return a; -+} -+ -+static int jent_gcd_analyze_internal(uint64_t *delta_history, size_t nelem, -+ uint64_t *running_gcd_out, -+ uint64_t *delta_sum_out) -+{ -+ uint64_t running_gcd, delta_sum = 0; -+ size_t i; -+ -+ if (!delta_history) -+ return -EAGAIN; -+ -+ running_gcd = delta_history[0]; -+ -+ /* Now perform the analysis on the accumulated delta data. */ -+ for (i = 1; i < nelem; i++) { -+ /* -+ * ensure that we have a varying delta timer which is necessary -+ * for the calculation of entropy -- perform this check -+ * only after the first loop is executed as we need to prime -+ * the old_data value -+ */ -+ if (delta_history[i] >= delta_history[i - 1]) -+ delta_sum += delta_history[i] - delta_history[i - 1]; -+ else -+ delta_sum += delta_history[i - 1] - delta_history[i]; -+ -+ /* -+ * This calculates the gcd of all the delta values. that is -+ * gcd(delta_1, delta_2, ..., delta_nelem) -+ -+ * Some timers increment by a fixed (non-1) amount each step. -+ * This code checks for such increments, and allows the library -+ * to output the number of such changes have occurred. -+ */ -+ running_gcd = jent_gcd64(delta_history[i], running_gcd); -+ } -+ -+ *running_gcd_out = running_gcd; -+ *delta_sum_out = delta_sum; -+ -+ return 0; -+} -+ -+int jent_gcd_analyze(uint64_t *delta_history, size_t nelem) -+{ -+ uint64_t running_gcd, delta_sum; -+ int ret = jent_gcd_analyze_internal(delta_history, nelem, &running_gcd, -+ &delta_sum); -+ -+ if (ret == -EAGAIN) -+ return 0; -+ -+ /* -+ * Variations of deltas of time must on average be larger than 1 to -+ * ensure the entropy estimation implied with 1 is preserved. -+ */ -+ if (delta_sum <= nelem - 1) { -+ ret = EMINVARVAR; -+ goto out; -+ } -+ -+ /* -+ * Ensure that we have variations in the time stamp below 100 for at -+ * least 10% of all checks -- on some platforms, the counter increments -+ * in multiples of 100, but not always -+ */ -+ if (running_gcd >= 100) { -+ ret = ECOARSETIME; -+ goto out; -+ } -+ -+ /* Adjust all deltas by the observed (small) common factor. */ -+ if (!jent_gcd_tested()) -+ jent_common_timer_gcd = running_gcd; -+ -+out: -+ return ret; -+} -+ -+uint64_t *jent_gcd_init(size_t nelem) -+{ -+ uint64_t *delta_history; -+ -+ delta_history = jent_zalloc(nelem * sizeof(uint64_t)); -+ if (!delta_history) -+ return NULL; -+ -+ return delta_history; -+} -+ -+void jent_gcd_fini(uint64_t *delta_history, size_t nelem) -+{ -+ if (delta_history) -+ jent_zfree(delta_history, -+ (unsigned int)(nelem * sizeof(uint64_t))); -+} -+ -+int jent_gcd_get(uint64_t *value) -+{ -+ if (!jent_gcd_tested()) -+ return 1; -+ -+ *value = jent_common_timer_gcd; -+ return 0; -+} -+ -+int jent_gcd_selftest(void) -+{ -+#define JENT_GCD_SELFTEST_ELEM 10 -+#define JENT_GCD_SELFTEST_EXP 3ULL -+ uint64_t *gcd = jent_gcd_init(JENT_GCD_SELFTEST_ELEM); -+ uint64_t running_gcd, delta_sum; -+ unsigned int i; -+ int ret = EGCD; -+ -+ if (!gcd) -+ return EMEM; -+ -+ for (i = 0; i < JENT_GCD_SELFTEST_ELEM; i++) -+ jent_gcd_add_value(gcd, i * JENT_GCD_SELFTEST_EXP, i); -+ -+ if (jent_gcd_analyze_internal(gcd, JENT_GCD_SELFTEST_ELEM, -+ &running_gcd, &delta_sum)) -+ goto out; -+ -+ if (running_gcd != JENT_GCD_SELFTEST_EXP) -+ goto out; -+ -+ ret = 0; -+ -+out: -+ jent_gcd_fini(gcd, JENT_GCD_SELFTEST_ELEM); -+ return ret; -+} -Index: libgcrypt-1.9.4/random/jitterentropy-gcd.h -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-gcd.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#ifndef JITTERENTROPY_GCD_H -+#define JITTERENTROPY_GCD_H -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+int jent_gcd_analyze(uint64_t *delta_history, size_t nelem); -+uint64_t *jent_gcd_init(size_t nelem); -+void jent_gcd_fini(uint64_t *delta_history, size_t nelem); -+int jent_gcd_get(uint64_t *value); -+int jent_gcd_selftest(void); -+ -+/* Watch for common adjacent GCD values */ -+#define jent_gcd_add_value(delta_history, delta, idx) \ -+ delta_history[idx] = delta; -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* JITTERENTROPY_GCD_H */ -Index: libgcrypt-1.9.4/random/jitterentropy.h -=================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy.h -+++ libgcrypt-1.9.4/random/jitterentropy.h -@@ -42,11 +42,122 @@ - #ifndef _JITTERENTROPY_H - #define _JITTERENTROPY_H - --#ifdef __KERNEL__ --#include "jitterentropy-base-kernel.h" --#else -+/*************************************************************************** -+ * Jitter RNG Configuration Section -+ * -+ * You may alter the following options -+ ***************************************************************************/ -+ -+/* -+ * Enable timer-less timer support -+ * -+ * In case the hardware is identified to not provide a high-resolution time -+ * stamp, this option enables a built-in high-resolution time stamp mechanism. -+ * -+ * The timer-less noise source is based on threads. This noise source requires -+ * the linking with the POSIX threads library. I.e. the executing environment -+ * must offer POSIX threads. If this option is disabled, no linking -+ * with the POSIX threads library is needed. -+ */ -+#undef JENT_CONF_ENABLE_INTERNAL_TIMER -+ -+/* -+ * Disable the loop shuffle operation -+ * -+ * The shuffle operation enlarges the timing of the conditioning function -+ * by a variable length defined by the LSB of a time stamp. Some mathematicians -+ * are concerned that this pseudo-random selection of the loop iteration count -+ * may create some form of dependency between the different loop counts -+ * and the associated time duration of the conditioning function. It -+ * also complicates entropy assessment because it effectively combines a bunch -+ * of shifted/scaled copies the same distribution and masks failures from the -+ * health testing. -+ * -+ * By enabling this flag, the loop shuffle operation is disabled and -+ * the entropy collection operates in a way that honor the concerns. -+ * -+ * By enabling this flag, the time of collecting entropy may be enlarged. -+ */ -+#define JENT_CONF_DISABLE_LOOP_SHUFFLE -+ -+/* -+ * Shall the LAG predictor health test be enabled? -+ */ -+#define JENT_HEALTH_LAG_PREDICTOR -+ -+/* -+ * Shall the jent_memaccess use a (statistically) random selection for the -+ * memory to update? -+ */ -+#define JENT_RANDOM_MEMACCESS -+ -+/*************************************************************************** -+ * Jitter RNG State Definition Section -+ ***************************************************************************/ -+ - #include "jitterentropy-base-user.h" --#endif /* __KERNEL__ */ -+ -+#define SHA3_256_SIZE_DIGEST_BITS 256 -+#define SHA3_256_SIZE_DIGEST (SHA3_256_SIZE_DIGEST_BITS >> 3) -+ -+/* -+ * The output 256 bits can receive more than 256 bits of min entropy, -+ * of course, but the 256-bit output of SHA3-256(M) can only asymptotically -+ * approach 256 bits of min entropy, not attain that bound. Random maps will -+ * tend to have output collisions, which reduces the creditable output entropy -+ * (that is what SP 800-90B Section 3.1.5.1.2 attempts to bound). -+ * -+ * The value "64" is justified in Appendix A.4 of the current 90C draft, -+ * and aligns with NIST's in "epsilon" definition in this document, which is -+ * that a string can be considered "full entropy" if you can bound the min -+ * entropy in each bit of output to at least 1-epsilon, where epsilon is -+ * required to be <= 2^(-32). -+ */ -+#define ENTROPY_SAFETY_FACTOR 64 -+ -+/** -+ * Function pointer data structure to register an external thread handler -+ * used for the timer-less mode of the Jitter RNG. -+ * -+ * The external caller provides these function pointers to handle the -+ * management of the timer thread that is spawned by the Jitter RNG. -+ * -+ * @var jent_notime_init This function is intended to initialze the threading -+ * support. All data that is required by the threading code must be -+ * held in the data structure @param ctx. The Jitter RNG maintains the -+ * data structure and uses it for every invocation of the following calls. -+ * -+ * @var jent_notime_fini This function shall terminate the threading support. -+ * The function must dispose of all memory and resources used for the -+ * threading operation. It must also dispose of the @param ctx memory. -+ * -+ * @var jent_notime_start This function is called when the Jitter RNG wants -+ * to start a thread. Besides providing a pointer to the @param ctx -+ * allocated during initialization time, the Jitter RNG provides a -+ * pointer to the function the thread shall execute and the argument -+ * the function shall be invoked with. These two parameters have the -+ * same purpose as the trailing two parameters of pthread_create(3). -+ * -+ * @var jent_notime_stop This function is invoked by the Jitter RNG when the -+ * thread should be stopped. Note, the Jitter RNG intends to start/stop -+ * the thread frequently. -+ * -+ * An example implementation is found in the Jitter RNG itself with its -+ * default thread handler of jent_notime_thread_builtin. -+ * -+ * If the caller wants to register its own thread handler, it must be done -+ * with the API call jent_entropy_switch_notime_impl as the first -+ * call to interact with the Jitter RNG, even before jent_entropy_init. -+ * After jent_entropy_init is called, changing of the threading implementation -+ * is not allowed. -+ */ -+struct jent_notime_thread { -+ int (*jent_notime_init)(void **ctx); -+ void (*jent_notime_fini)(void *ctx); -+ int (*jent_notime_start)(void *ctx, -+ void *(*start_routine) (void *), void *arg); -+ void (*jent_notime_stop)(void *ctx); -+}; - - /* The entropy pool */ - struct rand_data -@@ -55,35 +166,179 @@ struct rand_data - * of the RNG are marked as SENSITIVE. A user must not - * access that information while the RNG executes its loops to - * calculate the next random value. */ -- uint64_t data; /* SENSITIVE Actual random number */ -- uint64_t old_data; /* SENSITIVE Previous random number */ -- uint64_t prev_time; /* SENSITIVE Previous time stamp */ --#define DATA_SIZE_BITS ((sizeof(uint64_t)) * 8) -- uint64_t last_delta; /* SENSITIVE stuck test */ -- int64_t last_delta2; /* SENSITIVE stuck test */ -- unsigned int osr; /* Oversample rate */ -- int fips_enabled; /* FIPS enabled? */ -- unsigned int stir:1; /* Post-processing stirring */ -- unsigned int disable_unbias:1; /* Deactivate Von-Neuman unbias */ --#define JENT_MEMORY_BLOCKS 64 --#define JENT_MEMORY_BLOCKSIZE 32 -+ uint8_t data[SHA3_256_SIZE_DIGEST]; /* SENSITIVE Actual random number */ -+ uint64_t prev_time; /* SENSITIVE Previous time stamp */ -+#define DATA_SIZE_BITS (SHA3_256_SIZE_DIGEST_BITS) -+ -+#ifndef JENT_HEALTH_LAG_PREDICTOR -+ uint64_t last_delta; /* SENSITIVE stuck test */ -+ uint64_t last_delta2; /* SENSITIVE stuck test */ -+#endif /* JENT_HEALTH_LAG_PREDICTOR */ -+ -+ unsigned int flags; /* Flags used to initialize */ -+ unsigned int osr; /* Oversampling rate */ -+ -+#ifdef JENT_RANDOM_MEMACCESS -+ /* The step size should be larger than the cacheline size. */ -+# ifndef JENT_MEMORY_BITS -+# define JENT_MEMORY_BITS 17 -+# endif -+# ifndef JENT_MEMORY_SIZE -+# define JENT_MEMORY_SIZE (UINT32_C(1)<> JENT_FLAGS_TO_MEMSIZE_SHIFT) -+#define JENT_MAX_MEMSIZE_TO_FLAGS(val) (val << JENT_FLAGS_TO_MEMSIZE_SHIFT) -+#define JENT_MAX_MEMSIZE_32kB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C( 1)) -+#define JENT_MAX_MEMSIZE_64kB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C( 2)) -+#define JENT_MAX_MEMSIZE_128kB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C( 3)) -+#define JENT_MAX_MEMSIZE_256kB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C( 4)) -+#define JENT_MAX_MEMSIZE_512kB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C( 5)) -+#define JENT_MAX_MEMSIZE_1MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C( 6)) -+#define JENT_MAX_MEMSIZE_2MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C( 7)) -+#define JENT_MAX_MEMSIZE_4MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C( 8)) -+#define JENT_MAX_MEMSIZE_8MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C( 9)) -+#define JENT_MAX_MEMSIZE_16MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C(10)) -+#define JENT_MAX_MEMSIZE_32MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C(11)) -+#define JENT_MAX_MEMSIZE_64MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C(12)) -+#define JENT_MAX_MEMSIZE_128MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C(13)) -+#define JENT_MAX_MEMSIZE_256MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C(14)) -+#define JENT_MAX_MEMSIZE_512MB JENT_MAX_MEMSIZE_TO_FLAGS(UINT32_C(15)) -+#define JENT_MAX_MEMSIZE_MAX JENT_MAX_MEMSIZE_512MB -+#define JENT_MAX_MEMSIZE_MASK JENT_MAX_MEMSIZE_MAX -+/* We start at 32kB -> offset is log2(32768) */ -+#define JENT_MAX_MEMSIZE_OFFSET 14 -+ -+#ifdef JENT_CONF_DISABLE_LOOP_SHUFFLE -+# define JENT_MIN_OSR 3 -+#else -+# define JENT_MIN_OSR 1 -+#endif -+ -+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - - /* -- BEGIN Main interface functions -- */ - -@@ -94,19 +349,21 @@ struct rand_data - * - * It is allowed to change this value as required for the intended environment. - */ --#define JENT_STUCK_INIT_THRES(x) (x/10 * 9) -+#define JENT_STUCK_INIT_THRES(x) ((x*9) / 10) - #endif - - #ifdef JENT_PRIVATE_COMPILE - # define JENT_PRIVATE_STATIC static - #else /* JENT_PRIVATE_COMPILE */ --# define JENT_PRIVATE_STATIC -+# define JENT_PRIVATE_STATIC __attribute__((visibility("default"))) - #endif - - /* Number of low bits of the time value that we want to consider */ - /* get raw entropy */ - JENT_PRIVATE_STATIC - ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len); -+JENT_PRIVATE_STATIC -+ssize_t jent_read_entropy_safe(struct rand_data **ec, char *data, size_t len); - /* initialize an instance of the entropy collector */ - JENT_PRIVATE_STATIC - struct rand_data *jent_entropy_collector_alloc(unsigned int osr, -@@ -118,13 +375,47 @@ void jent_entropy_collector_free(struct - /* initialization of entropy collector */ - JENT_PRIVATE_STATIC - int jent_entropy_init(void); -+JENT_PRIVATE_STATIC -+int jent_entropy_init_ex(unsigned int osr, unsigned int flags); - - /* return version number of core library */ - JENT_PRIVATE_STATIC - unsigned int jent_version(void); - -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+/* Set a different thread handling logic for the notimer support */ -+JENT_PRIVATE_STATIC -+int jent_entropy_switch_notime_impl(struct jent_notime_thread *new_thread); -+#endif -+ - /* -- END of Main interface functions -- */ - -+/* -- BEGIN timer-less threading support functions to prevent code dupes -- */ -+ -+struct jent_notime_ctx { -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+ pthread_attr_t notime_pthread_attr; /* pthreads library */ -+ pthread_t notime_thread_id; /* pthreads thread ID */ -+#endif -+}; -+ -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+ -+JENT_PRIVATE_STATIC -+int jent_notime_init(void **ctx); -+ -+JENT_PRIVATE_STATIC -+void jent_notime_fini(void *ctx); -+ -+#else -+ -+static inline int jent_notime_init(void **ctx) { (void)ctx; return 0; } -+static inline void jent_notime_fini(void *ctx) { (void)ctx; } -+ -+#endif /* JENT_CONF_ENABLE_INTERNAL_TIMER */ -+ -+/* -- END timer-less threading support functions to prevent code dupes -- */ -+ - /* -- BEGIN error codes for init function -- */ - #define ENOTIME 1 /* Timer service not available */ - #define ECOARSETIME 2 /* Timer too coarse for RNG */ -@@ -135,6 +426,18 @@ unsigned int jent_version(void); - #define EMINVARVAR 6 /* Timer variations of variations is too small */ - #define EPROGERR 7 /* Programming error */ - #define ESTUCK 8 /* Too many stuck results during init. */ -+#define EHEALTH 9 /* Health test failed during initialization */ -+#define ERCT 10 /* RCT failed during initialization */ -+#define EHASH 11 /* Hash self test failed */ -+#define EMEM 12 /* Can't allocate memory for initialization */ -+#define EGCD 13 /* GCD self-test failed */ -+/* -- END error codes for init function -- */ -+ -+/* -- BEGIN error masks for health tests -- */ -+#define JENT_RCT_FAILURE 1 /* Failure in RCT health test. */ -+#define JENT_APT_FAILURE 2 /* Failure in APT health test. */ -+#define JENT_LAG_FAILURE 4 /* Failure in Lag predictor health test. */ -+/* -- END error masks for health tests -- */ - - /* -- BEGIN statistical test functions only complied with CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -- */ - -Index: libgcrypt-1.9.4/random/jitterentropy-health.c -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-health.c -@@ -0,0 +1,438 @@ -+/* Jitter RNG: Health Tests -+ * -+ * Copyright (C) 2021, Joshua E. Hill -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#include "jitterentropy.h" -+#include "jitterentropy-health.h" -+ -+/*************************************************************************** -+ * Lag Predictor Test -+ * -+ * This test is a vendor-defined conditional test that is designed to detect -+ * a known failure mode where the result becomes mostly deterministic -+ * Note that (lag_observations & JENT_LAG_MASK) is the index where the next -+ * value provided will be stored. -+ ***************************************************************************/ -+ -+#ifdef JENT_HEALTH_LAG_PREDICTOR -+ -+/* -+ * These cutoffs are configured using an entropy estimate of 1/osr under an -+ * alpha=2^(-22) for a window size of 131072. The other health tests use -+ * alpha=2^-30, but operate on much smaller window sizes. This larger selection -+ * of alpha makes the behavior per-lag-window similar to the APT test. -+ * -+ * The global cutoffs are calculated using the -+ * InverseBinomialCDF(n=(JENT_LAG_WINDOW_SIZE-JENT_LAG_HISTORY_SIZE), p=2^(-1/osr); 1-alpha) -+ * The local cutoffs are somewhat more complicated. For background, see Feller's -+ * _Introduction to Probability Theory and It's Applications_ Vol. 1, -+ * Chapter 13, section 7 (in particular see equation 7.11, where x is a root -+ * of the denominator of equation 7.6). -+ * -+ * We'll proceed using the notation of SP 800-90B Section 6.3.8 (which is -+ * developed in Kelsey-McKay-Turan paper "Predictive Models for Min-entropy -+ * Estimation".) -+ * -+ * Here, we set p=2^(-1/osr), seeking a run of successful guesses (r) with -+ * probability of less than (1-alpha). That is, it is very very likely -+ * (probability 1-alpha) that there is _no_ run of length r in a block of size -+ * JENT_LAG_WINDOW_SIZE-JENT_LAG_HISTORY_SIZE. -+ * -+ * We have to iteratively look for an appropriate value for the cutoff r. -+ */ -+static const unsigned int jent_lag_global_cutoff_lookup[20] = -+ { 66443, 93504, 104761, 110875, 114707, 117330, 119237, 120686, 121823, -+ 122739, 123493, 124124, 124660, 125120, 125520, 125871, 126181, 126457, -+ 126704, 126926 }; -+static const unsigned int jent_lag_local_cutoff_lookup[20] = -+ { 38, 75, 111, 146, 181, 215, 250, 284, 318, 351, -+ 385, 419, 452, 485, 518, 551, 584, 617, 650, 683 }; -+ -+void jent_lag_init(struct rand_data *ec, unsigned int osr) -+{ -+ /* -+ * Establish the lag global and local cutoffs based on the presumed -+ * entropy rate of 1/osr. -+ */ -+ if (osr > ARRAY_SIZE(jent_lag_global_cutoff_lookup)) { -+ ec->lag_global_cutoff = -+ jent_lag_global_cutoff_lookup[ -+ ARRAY_SIZE(jent_lag_global_cutoff_lookup) - 1]; -+ } else { -+ ec->lag_global_cutoff = jent_lag_global_cutoff_lookup[osr - 1]; -+ } -+ -+ if (osr > ARRAY_SIZE(jent_lag_local_cutoff_lookup)) { -+ ec->lag_local_cutoff = -+ jent_lag_local_cutoff_lookup[ -+ ARRAY_SIZE(jent_lag_local_cutoff_lookup) - 1]; -+ } else { -+ ec->lag_local_cutoff = jent_lag_local_cutoff_lookup[osr - 1]; -+ } -+} -+ -+/** -+ * Reset the lag counters -+ * -+ * @ec [in] Reference to entropy collector -+ */ -+static void jent_lag_reset(struct rand_data *ec) -+{ -+ unsigned int i; -+ -+ /* Reset Lag counters */ -+ ec->lag_prediction_success_count = 0; -+ ec->lag_prediction_success_run = 0; -+ ec->lag_best_predictor = 0; //The first guess is basically arbitrary. -+ ec->lag_observations = 0; -+ -+ for (i = 0; i < JENT_LAG_HISTORY_SIZE; i++) { -+ ec->lag_scoreboard[i] = 0; -+ ec->lag_delta_history[i] = 0; -+ } -+} -+ -+/* -+ * A macro for accessing the history. Index 0 is the last observed symbol -+ * index 1 is the symbol observed two inputs ago, etc. -+ */ -+#define JENT_LAG_HISTORY(EC,LOC) \ -+ ((EC)->lag_delta_history[((EC)->lag_observations - (LOC) - 1) & \ -+ JENT_LAG_MASK]) -+ -+/** -+ * Insert a new entropy event into the lag predictor test -+ * -+ * @ec [in] Reference to entropy collector -+ * @current_delta [in] Current time delta -+ */ -+static void jent_lag_insert(struct rand_data *ec, uint64_t current_delta) -+{ -+ uint64_t prediction; -+ unsigned int i; -+ -+ /* Initialize the delta_history */ -+ if (ec->lag_observations < JENT_LAG_HISTORY_SIZE) { -+ ec->lag_delta_history[ec->lag_observations] = current_delta; -+ ec->lag_observations++; -+ return; -+ } -+ -+ /* -+ * The history is initialized. First make a guess and examine the -+ * results. -+ */ -+ prediction = JENT_LAG_HISTORY(ec, ec->lag_best_predictor); -+ -+ if (prediction == current_delta) { -+ /* The prediction was correct. */ -+ ec->lag_prediction_success_count++; -+ ec->lag_prediction_success_run++; -+ -+ if ((ec->lag_prediction_success_run >= ec->lag_local_cutoff) || -+ (ec->lag_prediction_success_count >= ec->lag_global_cutoff)) -+ ec->health_failure |= JENT_LAG_FAILURE; -+ } else { -+ /* The prediction wasn't correct. End any run of successes.*/ -+ ec->lag_prediction_success_run = 0; -+ } -+ -+ /* Now update the predictors using the current data. */ -+ for (i = 0; i < JENT_LAG_HISTORY_SIZE; i++) { -+ if (JENT_LAG_HISTORY(ec, i) == current_delta) { -+ /* -+ * The ith predictor (which guesses i + 1 symbols in -+ * the past) successfully guessed. -+ */ -+ ec->lag_scoreboard[i] ++; -+ -+ /* -+ * Keep track of the best predictor (tie goes to the -+ * shortest lag) -+ */ -+ if (ec->lag_scoreboard[i] > -+ ec->lag_scoreboard[ec->lag_best_predictor]) -+ ec->lag_best_predictor = i; -+ } -+ } -+ -+ /* -+ * Finally, update the lag_delta_history array with the newly input -+ * value. -+ */ -+ ec->lag_delta_history[(ec->lag_observations) & JENT_LAG_MASK] = -+ current_delta; -+ ec->lag_observations++; -+ -+ /* -+ * lag_best_predictor now is the index of the predictor with the largest -+ * number of correct guesses. -+ * This establishes our next guess. -+ */ -+ -+ /* Do we now need a new window? */ -+ if (ec->lag_observations >= JENT_LAG_WINDOW_SIZE) -+ jent_lag_reset(ec); -+} -+ -+static inline uint64_t jent_delta2(struct rand_data *ec, uint64_t current_delta) -+{ -+ /* Note that delta2_n = delta_n - delta_{n-1} */ -+ return jent_delta(JENT_LAG_HISTORY(ec, 0), current_delta); -+} -+ -+static inline uint64_t jent_delta3(struct rand_data *ec, uint64_t delta2) -+{ -+ /* -+ * Note that delta3_n = delta2_n - delta2_{n-1} -+ * = delta2_n - (delta_{n-1} - delta_{n-2}) -+ */ -+ return jent_delta(jent_delta(JENT_LAG_HISTORY(ec, 1), -+ JENT_LAG_HISTORY(ec, 0)), delta2); -+} -+ -+#else /* JENT_HEALTH_LAG_PREDICTOR */ -+ -+static inline void jent_lag_insert(struct rand_data *ec, uint64_t current_delta) -+{ -+ (void)ec; -+ (void)current_delta; -+} -+ -+static inline uint64_t jent_delta2(struct rand_data *ec, uint64_t current_delta) -+{ -+ uint64_t delta2 = jent_delta(ec->last_delta, current_delta); -+ -+ ec->last_delta = current_delta; -+ return delta2; -+} -+ -+static inline uint64_t jent_delta3(struct rand_data *ec, uint64_t delta2) -+{ -+ uint64_t delta3 = jent_delta(ec->last_delta2, delta2); -+ -+ ec->last_delta2 = delta2; -+ return delta3; -+} -+ -+#endif /* JENT_HEALTH_LAG_PREDICTOR */ -+ -+/*************************************************************************** -+ * Adaptive Proportion Test -+ * -+ * This test complies with SP800-90B section 4.4.2. -+ ***************************************************************************/ -+ -+/* -+ * See the SP 800-90B comment #10b for the corrected cutoff for the SP 800-90B -+ * APT. -+ * http://www.untruth.org/~josh/sp80090b/UL%20SP800-90B-final%20comments%20v1.9%2020191212.pdf -+ * In in the syntax of R, this is C = 2 + qbinom(1 - 2^(-30), 511, 2^(-1/osr)). -+ * (The original formula wasn't correct because the first symbol must -+ * necessarily have been observed, so there is no chance of observing 0 of these -+ * symbols.) -+ * -+ * For any value above 14, this yields the maximal allowable value of 512 -+ * (by FIPS 140-2 IG 7.19 Resolution # 16, we cannot choose a cutoff value that -+ * renders the test unable to fail). -+ */ -+static const unsigned int jent_apt_cutoff_lookup[15]= -+ { 325, 422, 459, 477, 488, 494, 499, 502, -+ 505, 507, 508, 509, 510, 511, 512 }; -+ -+void jent_apt_init(struct rand_data *ec, unsigned int osr) -+{ -+ /* -+ * Establish the apt_cutoff based on the presumed entropy rate of -+ * 1/osr. -+ */ -+ if (osr >= ARRAY_SIZE(jent_apt_cutoff_lookup)) { -+ ec->apt_cutoff = jent_apt_cutoff_lookup[ -+ ARRAY_SIZE(jent_apt_cutoff_lookup) - 1]; -+ } else { -+ ec->apt_cutoff = jent_apt_cutoff_lookup[osr - 1]; -+ } -+} -+ -+/** -+ * Reset the APT counter -+ * -+ * @ec [in] Reference to entropy collector -+ */ -+static void jent_apt_reset(struct rand_data *ec) -+{ -+ /* When reset, accept the _next_ value input as the new base. */ -+ ec->apt_base_set = 0; -+} -+ -+/** -+ * Insert a new entropy event into APT -+ * -+ * @ec [in] Reference to entropy collector -+ * @current_delta [in] Current time delta -+ */ -+static void jent_apt_insert(struct rand_data *ec, uint64_t current_delta) -+{ -+ /* Initialize the base reference */ -+ if (!ec->apt_base_set) { -+ ec->apt_base = current_delta; // APT Step 1 -+ ec->apt_base_set = 1; // APT Step 2 -+ -+ /* -+ * Reset APT counter -+ * Note that we've taken in the first symbol in the window. -+ */ -+ ec->apt_count = 1; // B = 1 -+ ec->apt_observations = 1; -+ -+ return; -+ } -+ -+ if (current_delta == ec->apt_base) { -+ ec->apt_count++; // B = B + 1 -+ -+ /* Note, ec->apt_count starts with one. */ -+ if (ec->apt_count >= ec->apt_cutoff) -+ ec->health_failure |= JENT_APT_FAILURE; -+ } -+ -+ ec->apt_observations++; -+ -+ /* Completed one window, the next symbol input will be new apt_base. */ -+ if (ec->apt_observations >= JENT_APT_WINDOW_SIZE) -+ jent_apt_reset(ec); // APT Step 4 -+} -+ -+/*************************************************************************** -+ * Stuck Test and its use as Repetition Count Test -+ * -+ * The Jitter RNG uses an enhanced version of the Repetition Count Test -+ * (RCT) specified in SP800-90B section 4.4.1. Instead of counting identical -+ * back-to-back values, the input to the RCT is the counting of the stuck -+ * values during the generation of one Jitter RNG output block. -+ * -+ * The RCT is applied with an alpha of 2^{-30} compliant to FIPS 140-2 IG 9.8. -+ * -+ * During the counting operation, the Jitter RNG always calculates the RCT -+ * cut-off value of C. If that value exceeds the allowed cut-off value, -+ * the Jitter RNG output block will be calculated completely but discarded at -+ * the end. The caller of the Jitter RNG is informed with an error code. -+ ***************************************************************************/ -+ -+/** -+ * Repetition Count Test as defined in SP800-90B section 4.4.1 -+ * -+ * @ec [in] Reference to entropy collector -+ * @stuck [in] Indicator whether the value is stuck -+ */ -+static void jent_rct_insert(struct rand_data *ec, int stuck) -+{ -+ /* -+ * If we have a count less than zero, a previous RCT round identified -+ * a failure. We will not overwrite it. -+ */ -+ if (ec->rct_count < 0) -+ return; -+ -+ if (stuck) { -+ ec->rct_count++; -+ -+ /* -+ * The cutoff value is based on the following consideration: -+ * alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8. -+ * In addition, we require an entropy value H of 1/osr as this -+ * is the minimum entropy required to provide full entropy. -+ * Note, we collect (DATA_SIZE_BITS + ENTROPY_SAFETY_FACTOR)*osr -+ * deltas for inserting them into the entropy pool which should -+ * then have (close to) DATA_SIZE_BITS bits of entropy in the -+ * conditioned output. -+ * -+ * Note, ec->rct_count (which equals to value B in the pseudo -+ * code of SP800-90B section 4.4.1) starts with zero. Hence -+ * we need to subtract one from the cutoff value as calculated -+ * following SP800-90B. Thus C = ceil(-log_2(alpha)/H) = 30*osr. -+ */ -+ if ((unsigned int)ec->rct_count >= (30 * ec->osr)) { -+ ec->rct_count = -1; -+ ec->health_failure |= JENT_RCT_FAILURE; -+ } -+ } else { -+ ec->rct_count = 0; -+ } -+} -+ -+/** -+ * Stuck test by checking the: -+ * 1st derivative of the jitter measurement (time delta) -+ * 2nd derivative of the jitter measurement (delta of time deltas) -+ * 3rd derivative of the jitter measurement (delta of delta of time deltas) -+ * -+ * All values must always be non-zero. -+ * -+ * @ec [in] Reference to entropy collector -+ * @current_delta [in] Jitter time delta -+ * -+ * @return -+ * 0 jitter measurement not stuck (good bit) -+ * 1 jitter measurement stuck (reject bit) -+ */ -+unsigned int jent_stuck(struct rand_data *ec, uint64_t current_delta) -+{ -+ uint64_t delta2 = jent_delta2(ec, current_delta); -+ uint64_t delta3 = jent_delta3(ec, delta2); -+ -+ /* -+ * Insert the result of the comparison of two back-to-back time -+ * deltas. -+ */ -+ jent_apt_insert(ec, current_delta); -+ jent_lag_insert(ec, current_delta); -+ -+ if (!current_delta || !delta2 || !delta3) { -+ /* RCT with a stuck bit */ -+ jent_rct_insert(ec, 1); -+ return 1; -+ } -+ -+ /* RCT with a non-stuck bit */ -+ jent_rct_insert(ec, 0); -+ -+ return 0; -+} -+ -+/** -+ * Report any health test failures -+ * -+ * @ec [in] Reference to entropy collector -+ * -+ * @return a bitmask indicating which tests failed -+ * 0 No health test failure -+ * 1 RCT failure -+ * 2 APT failure -+ * 4 Lag predictor test failure -+ */ -+unsigned int jent_health_failure(struct rand_data *ec) -+{ -+ /* Test is only enabled in FIPS mode */ -+ if (!ec->fips_enabled) -+ return 0; -+ -+ return ec->health_failure; -+} -Index: libgcrypt-1.9.4/random/jitterentropy-health.h -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-health.h -@@ -0,0 +1,51 @@ -+/* -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#ifndef JITTERENTROPY_HEALTH_H -+#define JITTERENTROPY_HEALTH_H -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+static inline uint64_t jent_delta(uint64_t prev, uint64_t next) -+{ -+ return (next - prev); -+} -+ -+#ifdef JENT_HEALTH_LAG_PREDICTOR -+void jent_lag_init(struct rand_data *ec, unsigned int osr); -+#else /* JENT_HEALTH_LAG_PREDICTOR */ -+static inline void jent_lag_init(struct rand_data *ec, unsigned int osr) -+{ -+ (void)ec; -+ (void)osr; -+} -+#endif /* JENT_HEALTH_LAG_PREDICTOR */ -+ -+void jent_apt_init(struct rand_data *ec, unsigned int osr); -+unsigned int jent_stuck(struct rand_data *ec, uint64_t current_delta); -+unsigned int jent_health_failure(struct rand_data *ec); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* JITTERENTROPY_HEALTH_H */ -Index: libgcrypt-1.9.4/random/jitterentropy-noise.c -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-noise.c -@@ -0,0 +1,387 @@ -+/* Jitter RNG: Noise Sources -+ * -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#include "jitterentropy-noise.h" -+#include "jitterentropy-health.h" -+#include "jitterentropy-timer.h" -+#include "jitterentropy-sha3.h" -+ -+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) -+ -+/*************************************************************************** -+ * Noise sources -+ ***************************************************************************/ -+ -+/** -+ * Update of the loop count used for the next round of -+ * an entropy collection. -+ * -+ * @ec [in] entropy collector struct -- may be NULL -+ * @bits [in] is the number of low bits of the timer to consider -+ * @min [in] is the number of bits we shift the timer value to the right at -+ * the end to make sure we have a guaranteed minimum value -+ * -+ * @return Newly calculated loop counter -+ */ -+static uint64_t jent_loop_shuffle(struct rand_data *ec, -+ unsigned int bits, unsigned int min) -+{ -+#ifdef JENT_CONF_DISABLE_LOOP_SHUFFLE -+ -+ (void)ec; -+ (void)bits; -+ -+ return (UINT64_C(1)<data[0]; -+ } -+ -+ /* -+ * We fold the time value as much as possible to ensure that as many -+ * bits of the time stamp are included as possible. -+ */ -+ for (i = 0; ((DATA_SIZE_BITS + bits - 1) / bits) > i; i++) { -+ shuffle ^= time & mask; -+ time = time >> bits; -+ } -+ -+ /* -+ * We add a lower boundary value to ensure we have a minimum -+ * RNG loop count. -+ */ -+ return (shuffle + (UINT64_C(1)< 63); -+ hash_loop_cnt = -+ jent_loop_shuffle(ec, MAX_HASH_LOOP, MIN_HASH_LOOP); -+ -+ sha3_256_init(&ctx); -+ -+ /* -+ * testing purposes -- allow test app to set the counter, not -+ * needed during runtime -+ */ -+ if (loop_cnt) -+ hash_loop_cnt = loop_cnt; -+ -+ /* -+ * This loop basically slows down the SHA-3 operation depending -+ * on the hash_loop_cnt. Each iteration of the loop generates the -+ * same result. -+ */ -+ for (j = 0; j < hash_loop_cnt; j++) { -+ sha3_update(&ctx, ec->data, SHA3_256_SIZE_DIGEST); -+ sha3_update(&ctx, (uint8_t *)&time, sizeof(uint64_t)); -+ sha3_update(&ctx, (uint8_t *)&j, sizeof(uint64_t)); -+ -+ /* -+ * If the time stamp is stuck, do not finally insert the value -+ * into the entropy pool. Although this operation should not do -+ * any harm even when the time stamp has no entropy, SP800-90B -+ * requires that any conditioning operation to have an identical -+ * amount of input data according to section 3.1.5. -+ */ -+ -+ /* -+ * The sha3_final operations re-initialize the context for the -+ * next loop iteration. -+ */ -+ if (stuck || (j < hash_loop_cnt - 1)) -+ sha3_final(&ctx, itermediary); -+ else -+ sha3_final(&ctx, ec->data); -+ } -+ -+ jent_memset_secure(&ctx, SHA_MAX_CTX_SIZE); -+ jent_memset_secure(itermediary, sizeof(itermediary)); -+} -+ -+#define MAX_ACC_LOOP_BIT 7 -+#define MIN_ACC_LOOP_BIT 0 -+#ifdef JENT_RANDOM_MEMACCESS -+ -+static inline uint32_t uint32rotl(const uint32_t x, int k) -+{ -+ return (x << k) | (x >> (32 - k)); -+} -+ -+static inline uint32_t xoshiro128starstar(uint32_t *s) -+{ -+ const uint32_t result = uint32rotl(s[1] * 5, 7) * 9; -+ const uint32_t t = s[1] << 9; -+ -+ s[2] ^= s[0]; -+ s[3] ^= s[1]; -+ s[1] ^= s[2]; -+ s[0] ^= s[3]; -+ -+ s[2] ^= t; -+ -+ s[3] = uint32rotl(s[3], 11); -+ -+ return result; -+} -+ -+static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) -+{ -+ uint64_t i = 0; -+ union { -+ uint32_t u[4]; -+ uint8_t b[sizeof(uint32_t) * 4]; -+ } prngState = { .u = {0x8e93eec0, 0xce65608a, 0xa8d46b46, 0xe83cef69} }; -+ uint32_t addressMask; -+ uint64_t acc_loop_cnt; -+ -+ if (NULL == ec || NULL == ec->mem) -+ return; -+ -+ addressMask = ec->memmask; -+ -+ /* Ensure that macros cannot overflow jent_loop_shuffle() */ -+ BUILD_BUG_ON((MAX_ACC_LOOP_BIT + MIN_ACC_LOOP_BIT) > 63); -+ acc_loop_cnt = -+ jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT); -+ -+ /* -+ * Mix the current data into prngState -+ * -+ * Any time you see a PRNG in a noise source, you should be concerned. -+ * -+ * The PRNG doesn't directly produce the raw noise, it just adjusts the -+ * location being updated. The timing of the update is part of the raw -+ * sample. The main thing this process gets you isn't better -+ * "per-update: timing, it gets you mostly independent "per-update" -+ * timing, so we can now benefit from the Central Limit Theorem! -+ */ -+ for (i = 0; i < sizeof(prngState); i++) -+ prngState.b[i] ^= ec->data[i]; -+ -+ /* -+ * testing purposes -- allow test app to set the counter, not -+ * needed during runtime -+ */ -+ if (loop_cnt) -+ acc_loop_cnt = loop_cnt; -+ -+ for (i = 0; i < (ec->memaccessloops + acc_loop_cnt); i++) { -+ /* Take PRNG output to find the memory location to update. */ -+ unsigned char *tmpval = ec->mem + -+ (xoshiro128starstar(prngState.u) & -+ addressMask); -+ -+ /* -+ * memory access: just add 1 to one byte, -+ * wrap at 255 -- memory access implies read -+ * from and write to memory location -+ */ -+ *tmpval = (unsigned char)((*tmpval + 1) & 0xff); -+ } -+} -+ -+#else /* JENT_RANDOM_MEMACCESS */ -+ -+/** -+ * Memory Access noise source -- this is a noise source based on variations in -+ * memory access times -+ * -+ * This function performs memory accesses which will add to the timing -+ * variations due to an unknown amount of CPU wait states that need to be -+ * added when accessing memory. The memory size should be larger than the L1 -+ * caches as outlined in the documentation and the associated testing. -+ * -+ * The L1 cache has a very high bandwidth, albeit its access rate is usually -+ * slower than accessing CPU registers. Therefore, L1 accesses only add minimal -+ * variations as the CPU has hardly to wait. Starting with L2, significant -+ * variations are added because L2 typically does not belong to the CPU any more -+ * and therefore a wider range of CPU wait states is necessary for accesses. -+ * L3 and real memory accesses have even a wider range of wait states. However, -+ * to reliably access either L3 or memory, the ec->mem memory must be quite -+ * large which is usually not desirable. -+ * -+ * @ec [in] Reference to the entropy collector with the memory access data -- if -+ * the reference to the memory block to be accessed is NULL, this noise -+ * source is disabled -+ * @loop_cnt [in] if a value not equal to 0 is set, use the given value as -+ * number of loops to perform the hash operation -+ */ -+static void jent_memaccess(struct rand_data *ec, uint64_t loop_cnt) -+{ -+ unsigned int wrap = 0; -+ uint64_t i = 0; -+ -+ /* Ensure that macros cannot overflow jent_loop_shuffle() */ -+ BUILD_BUG_ON((MAX_ACC_LOOP_BIT + MIN_ACC_LOOP_BIT) > 63); -+ uint64_t acc_loop_cnt = -+ jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT); -+ -+ if (NULL == ec || NULL == ec->mem) -+ return; -+ wrap = ec->memblocksize * ec->memblocks; -+ -+ /* -+ * testing purposes -- allow test app to set the counter, not -+ * needed during runtime -+ */ -+ if (loop_cnt) -+ acc_loop_cnt = loop_cnt; -+ for (i = 0; i < (ec->memaccessloops + acc_loop_cnt); i++) { -+ unsigned char *tmpval = ec->mem + ec->memlocation; -+ /* -+ * memory access: just add 1 to one byte, -+ * wrap at 255 -- memory access implies read -+ * from and write to memory location -+ */ -+ *tmpval = (unsigned char)((*tmpval + 1) & 0xff); -+ /* -+ * Addition of memblocksize - 1 to pointer -+ * with wrap around logic to ensure that every -+ * memory location is hit evenly -+ */ -+ ec->memlocation = ec->memlocation + ec->memblocksize - 1; -+ ec->memlocation = ec->memlocation % wrap; -+ } -+} -+ -+#endif /* JENT_RANDOM_MEMACCESS */ -+ -+/*************************************************************************** -+ * Start of entropy processing logic -+ ***************************************************************************/ -+ -+/** -+ * This is the heart of the entropy generation: calculate time deltas and -+ * use the CPU jitter in the time deltas. The jitter is injected into the -+ * entropy pool. -+ * -+ * WARNING: ensure that ->prev_time is primed before using the output -+ * of this function! This can be done by calling this function -+ * and not using its result. -+ * -+ * @ec [in] Reference to entropy collector -+ * @loop_cnt [in] see jent_hash_time -+ * @ret_current_delta [out] Test interface: return time delta - may be NULL -+ * -+ * @return: result of stuck test -+ */ -+unsigned int jent_measure_jitter(struct rand_data *ec, -+ uint64_t loop_cnt, -+ uint64_t *ret_current_delta) -+{ -+ uint64_t time = 0; -+ uint64_t current_delta = 0; -+ unsigned int stuck; -+ -+ /* Invoke one noise source before time measurement to add variations */ -+ jent_memaccess(ec, loop_cnt); -+ -+ /* -+ * Get time stamp and calculate time delta to previous -+ * invocation to measure the timing variations -+ */ -+ jent_get_nstime_internal(ec, &time); -+ current_delta = jent_delta(ec->prev_time, time) / -+ ec->jent_common_timer_gcd; -+ ec->prev_time = time; -+ -+ /* Check whether we have a stuck measurement. */ -+ stuck = jent_stuck(ec, current_delta); -+ -+ /* Now call the next noise sources which also injects the data */ -+ jent_hash_time(ec, current_delta, loop_cnt, stuck); -+ -+ /* return the raw entropy value */ -+ if (ret_current_delta) -+ *ret_current_delta = current_delta; -+ -+ return stuck; -+} -+ -+/** -+ * Generator of one 256 bit random number -+ * Function fills rand_data->data -+ * -+ * @ec [in] Reference to entropy collector -+ */ -+void jent_random_data(struct rand_data *ec) -+{ -+ unsigned int k = 0, safety_factor = ENTROPY_SAFETY_FACTOR; -+ -+ if (!ec->fips_enabled) -+ safety_factor = 0; -+ -+ /* priming of the ->prev_time value */ -+ jent_measure_jitter(ec, 0, NULL); -+ -+ while (1) { -+ /* If a stuck measurement is received, repeat measurement */ -+ if (jent_measure_jitter(ec, 0, NULL)) -+ continue; -+ -+ /* -+ * We multiply the loop value with ->osr to obtain the -+ * oversampling rate requested by the caller -+ */ -+ if (++k >= ((DATA_SIZE_BITS + safety_factor) * ec->osr)) -+ break; -+ } -+} -Index: libgcrypt-1.9.4/random/jitterentropy-noise.h -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-noise.h -@@ -0,0 +1,39 @@ -+/* -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#ifndef JITTERENTROPY_NOISE_H -+#define JITTERENTROPY_NOISE_H -+ -+#include "jitterentropy.h" -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+unsigned int jent_measure_jitter(struct rand_data *ec, -+ uint64_t loop_cnt, -+ uint64_t *ret_current_delta); -+void jent_random_data(struct rand_data *ec); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* JITTERENTROPY_NOISE_H */ -Index: libgcrypt-1.9.4/random/jitterentropy-sha3.c -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-sha3.c -@@ -0,0 +1,382 @@ -+/* Jitter RNG: SHA-3 Implementation -+ * -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#include "jitterentropy-sha3.h" -+ -+/*************************************************************************** -+ * Message Digest Implementation -+ ***************************************************************************/ -+ -+/* -+ * Conversion of Little-Endian representations in byte streams - the data -+ * representation in the integer values is the host representation. -+ */ -+static inline uint32_t ptr_to_le32(const uint8_t *p) -+{ -+ return (uint32_t)p[0] | (uint32_t)p[1] << 8 | -+ (uint32_t)p[2] << 16 | (uint32_t)p[3] << 24; -+} -+ -+static inline uint64_t ptr_to_le64(const uint8_t *p) -+{ -+ return (uint64_t)ptr_to_le32(p) | (uint64_t)ptr_to_le32(p + 4) << 32; -+} -+ -+static inline void le32_to_ptr(uint8_t *p, const uint32_t value) -+{ -+ p[0] = (uint8_t)(value); -+ p[1] = (uint8_t)(value >> 8); -+ p[2] = (uint8_t)(value >> 16); -+ p[3] = (uint8_t)(value >> 24); -+} -+ -+static inline void le64_to_ptr(uint8_t *p, const uint64_t value) -+{ -+ le32_to_ptr(p + 4, (uint32_t)(value >> 32)); -+ le32_to_ptr(p, (uint32_t)(value)); -+} -+ -+/*********************************** Keccak ***********************************/ -+/* state[x + y*5] */ -+#define A(x, y) (x + 5 * y) -+ -+static inline void keccakp_theta(uint64_t s[25]) -+{ -+ uint64_t C[5], D[5]; -+ -+ /* Step 1 */ -+ C[0] = s[A(0, 0)] ^ s[A(0, 1)] ^ s[A(0, 2)] ^ s[A(0, 3)] ^ s[A(0, 4)]; -+ C[1] = s[A(1, 0)] ^ s[A(1, 1)] ^ s[A(1, 2)] ^ s[A(1, 3)] ^ s[A(1, 4)]; -+ C[2] = s[A(2, 0)] ^ s[A(2, 1)] ^ s[A(2, 2)] ^ s[A(2, 3)] ^ s[A(2, 4)]; -+ C[3] = s[A(3, 0)] ^ s[A(3, 1)] ^ s[A(3, 2)] ^ s[A(3, 3)] ^ s[A(3, 4)]; -+ C[4] = s[A(4, 0)] ^ s[A(4, 1)] ^ s[A(4, 2)] ^ s[A(4, 3)] ^ s[A(4, 4)]; -+ -+ /* Step 2 */ -+ D[0] = C[4] ^ rol64(C[1], 1); -+ D[1] = C[0] ^ rol64(C[2], 1); -+ D[2] = C[1] ^ rol64(C[3], 1); -+ D[3] = C[2] ^ rol64(C[4], 1); -+ D[4] = C[3] ^ rol64(C[0], 1); -+ -+ /* Step 3 */ -+ s[A(0, 0)] ^= D[0]; -+ s[A(1, 0)] ^= D[1]; -+ s[A(2, 0)] ^= D[2]; -+ s[A(3, 0)] ^= D[3]; -+ s[A(4, 0)] ^= D[4]; -+ -+ s[A(0, 1)] ^= D[0]; -+ s[A(1, 1)] ^= D[1]; -+ s[A(2, 1)] ^= D[2]; -+ s[A(3, 1)] ^= D[3]; -+ s[A(4, 1)] ^= D[4]; -+ -+ s[A(0, 2)] ^= D[0]; -+ s[A(1, 2)] ^= D[1]; -+ s[A(2, 2)] ^= D[2]; -+ s[A(3, 2)] ^= D[3]; -+ s[A(4, 2)] ^= D[4]; -+ -+ s[A(0, 3)] ^= D[0]; -+ s[A(1, 3)] ^= D[1]; -+ s[A(2, 3)] ^= D[2]; -+ s[A(3, 3)] ^= D[3]; -+ s[A(4, 3)] ^= D[4]; -+ -+ s[A(0, 4)] ^= D[0]; -+ s[A(1, 4)] ^= D[1]; -+ s[A(2, 4)] ^= D[2]; -+ s[A(3, 4)] ^= D[3]; -+ s[A(4, 4)] ^= D[4]; -+} -+ -+static inline void keccakp_rho(uint64_t s[25]) -+{ -+ /* Step 1 */ -+ /* s[A(0, 0)] = s[A(0, 0)]; */ -+ -+#define RHO_ROL(t) (((t + 1) * (t + 2) / 2) % 64) -+ /* Step 3 */ -+ s[A(1, 0)] = rol64(s[A(1, 0)], RHO_ROL(0)); -+ s[A(0, 2)] = rol64(s[A(0, 2)], RHO_ROL(1)); -+ s[A(2, 1)] = rol64(s[A(2, 1)], RHO_ROL(2)); -+ s[A(1, 2)] = rol64(s[A(1, 2)], RHO_ROL(3)); -+ s[A(2, 3)] = rol64(s[A(2, 3)], RHO_ROL(4)); -+ s[A(3, 3)] = rol64(s[A(3, 3)], RHO_ROL(5)); -+ s[A(3, 0)] = rol64(s[A(3, 0)], RHO_ROL(6)); -+ s[A(0, 1)] = rol64(s[A(0, 1)], RHO_ROL(7)); -+ s[A(1, 3)] = rol64(s[A(1, 3)], RHO_ROL(8)); -+ s[A(3, 1)] = rol64(s[A(3, 1)], RHO_ROL(9)); -+ s[A(1, 4)] = rol64(s[A(1, 4)], RHO_ROL(10)); -+ s[A(4, 4)] = rol64(s[A(4, 4)], RHO_ROL(11)); -+ s[A(4, 0)] = rol64(s[A(4, 0)], RHO_ROL(12)); -+ s[A(0, 3)] = rol64(s[A(0, 3)], RHO_ROL(13)); -+ s[A(3, 4)] = rol64(s[A(3, 4)], RHO_ROL(14)); -+ s[A(4, 3)] = rol64(s[A(4, 3)], RHO_ROL(15)); -+ s[A(3, 2)] = rol64(s[A(3, 2)], RHO_ROL(16)); -+ s[A(2, 2)] = rol64(s[A(2, 2)], RHO_ROL(17)); -+ s[A(2, 0)] = rol64(s[A(2, 0)], RHO_ROL(18)); -+ s[A(0, 4)] = rol64(s[A(0, 4)], RHO_ROL(19)); -+ s[A(4, 2)] = rol64(s[A(4, 2)], RHO_ROL(20)); -+ s[A(2, 4)] = rol64(s[A(2, 4)], RHO_ROL(21)); -+ s[A(4, 1)] = rol64(s[A(4, 1)], RHO_ROL(22)); -+ s[A(1, 1)] = rol64(s[A(1, 1)], RHO_ROL(23)); -+} -+ -+static inline void keccakp_pi(uint64_t s[25]) -+{ -+ uint64_t t = s[A(4, 4)]; -+ -+ /* Step 1 */ -+ /* s[A(0, 0)] = s[A(0, 0)]; */ -+ s[A(4, 4)] = s[A(1, 4)]; -+ s[A(1, 4)] = s[A(3, 1)]; -+ s[A(3, 1)] = s[A(1, 3)]; -+ s[A(1, 3)] = s[A(0, 1)]; -+ s[A(0, 1)] = s[A(3, 0)]; -+ s[A(3, 0)] = s[A(3, 3)]; -+ s[A(3, 3)] = s[A(2, 3)]; -+ s[A(2, 3)] = s[A(1, 2)]; -+ s[A(1, 2)] = s[A(2, 1)]; -+ s[A(2, 1)] = s[A(0, 2)]; -+ s[A(0, 2)] = s[A(1, 0)]; -+ s[A(1, 0)] = s[A(1, 1)]; -+ s[A(1, 1)] = s[A(4, 1)]; -+ s[A(4, 1)] = s[A(2, 4)]; -+ s[A(2, 4)] = s[A(4, 2)]; -+ s[A(4, 2)] = s[A(0, 4)]; -+ s[A(0, 4)] = s[A(2, 0)]; -+ s[A(2, 0)] = s[A(2, 2)]; -+ s[A(2, 2)] = s[A(3, 2)]; -+ s[A(3, 2)] = s[A(4, 3)]; -+ s[A(4, 3)] = s[A(3, 4)]; -+ s[A(3, 4)] = s[A(0, 3)]; -+ s[A(0, 3)] = s[A(4, 0)]; -+ s[A(4, 0)] = t; -+} -+ -+static inline void keccakp_chi(uint64_t s[25]) -+{ -+ uint64_t t0[5], t1[5]; -+ -+ t0[0] = s[A(0, 0)]; -+ t0[1] = s[A(0, 1)]; -+ t0[2] = s[A(0, 2)]; -+ t0[3] = s[A(0, 3)]; -+ t0[4] = s[A(0, 4)]; -+ -+ t1[0] = s[A(1, 0)]; -+ t1[1] = s[A(1, 1)]; -+ t1[2] = s[A(1, 2)]; -+ t1[3] = s[A(1, 3)]; -+ t1[4] = s[A(1, 4)]; -+ -+ s[A(0, 0)] ^= ~s[A(1, 0)] & s[A(2, 0)]; -+ s[A(0, 1)] ^= ~s[A(1, 1)] & s[A(2, 1)]; -+ s[A(0, 2)] ^= ~s[A(1, 2)] & s[A(2, 2)]; -+ s[A(0, 3)] ^= ~s[A(1, 3)] & s[A(2, 3)]; -+ s[A(0, 4)] ^= ~s[A(1, 4)] & s[A(2, 4)]; -+ -+ s[A(1, 0)] ^= ~s[A(2, 0)] & s[A(3, 0)]; -+ s[A(1, 1)] ^= ~s[A(2, 1)] & s[A(3, 1)]; -+ s[A(1, 2)] ^= ~s[A(2, 2)] & s[A(3, 2)]; -+ s[A(1, 3)] ^= ~s[A(2, 3)] & s[A(3, 3)]; -+ s[A(1, 4)] ^= ~s[A(2, 4)] & s[A(3, 4)]; -+ -+ s[A(2, 0)] ^= ~s[A(3, 0)] & s[A(4, 0)]; -+ s[A(2, 1)] ^= ~s[A(3, 1)] & s[A(4, 1)]; -+ s[A(2, 2)] ^= ~s[A(3, 2)] & s[A(4, 2)]; -+ s[A(2, 3)] ^= ~s[A(3, 3)] & s[A(4, 3)]; -+ s[A(2, 4)] ^= ~s[A(3, 4)] & s[A(4, 4)]; -+ -+ s[A(3, 0)] ^= ~s[A(4, 0)] & t0[0]; -+ s[A(3, 1)] ^= ~s[A(4, 1)] & t0[1]; -+ s[A(3, 2)] ^= ~s[A(4, 2)] & t0[2]; -+ s[A(3, 3)] ^= ~s[A(4, 3)] & t0[3]; -+ s[A(3, 4)] ^= ~s[A(4, 4)] & t0[4]; -+ -+ s[A(4, 0)] ^= ~t0[0] & t1[0]; -+ s[A(4, 1)] ^= ~t0[1] & t1[1]; -+ s[A(4, 2)] ^= ~t0[2] & t1[2]; -+ s[A(4, 3)] ^= ~t0[3] & t1[3]; -+ s[A(4, 4)] ^= ~t0[4] & t1[4]; -+} -+ -+static const uint64_t keccakp_iota_vals[] = { -+ 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, -+ 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, -+ 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, -+ 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, -+ 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, -+ 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, -+ 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, -+ 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL -+}; -+ -+static inline void keccakp_iota(uint64_t s[25], unsigned int round) -+{ -+ s[0] ^= keccakp_iota_vals[round]; -+} -+ -+static inline void keccakp_1600(uint64_t s[25]) -+{ -+ unsigned int round; -+ -+ for (round = 0; round < 24; round++) { -+ keccakp_theta(s); -+ keccakp_rho(s); -+ keccakp_pi(s); -+ keccakp_chi(s); -+ keccakp_iota(s, round); -+ } -+} -+ -+/*********************************** SHA-3 ************************************/ -+ -+static inline void sha3_init(struct sha_ctx *ctx) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < 25; i++) -+ ctx->state[i] = 0; -+ ctx->msg_len = 0; -+} -+ -+void sha3_256_init(struct sha_ctx *ctx) -+{ -+ sha3_init(ctx); -+ ctx->r = SHA3_256_SIZE_BLOCK; -+ ctx->rword = SHA3_256_SIZE_BLOCK / sizeof(uint64_t); -+ ctx->digestsize = SHA3_256_SIZE_DIGEST; -+} -+ -+static inline void sha3_fill_state(struct sha_ctx *ctx, const uint8_t *in) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ctx->rword; i++) { -+ ctx->state[i] ^= ptr_to_le64(in); -+ in += 8; -+ } -+} -+ -+void sha3_update(struct sha_ctx *ctx, const uint8_t *in, size_t inlen) -+{ -+ size_t partial = ctx->msg_len % ctx->r; -+ -+ ctx->msg_len += inlen; -+ -+ /* Sponge absorbing phase */ -+ -+ /* Check if we have a partial block stored */ -+ if (partial) { -+ size_t todo = ctx->r - partial; -+ -+ /* -+ * If the provided data is small enough to fit in the partial -+ * buffer, copy it and leave it unprocessed. -+ */ -+ if (inlen < todo) { -+ memcpy(ctx->partial + partial, in, inlen); -+ return; -+ } -+ -+ /* -+ * The input data is large enough to fill the entire partial -+ * block buffer. Thus, we fill it and transform it. -+ */ -+ memcpy(ctx->partial + partial, in, todo); -+ inlen -= todo; -+ in += todo; -+ -+ sha3_fill_state(ctx, ctx->partial); -+ keccakp_1600(ctx->state); -+ } -+ -+ /* Perform a transformation of full block-size messages */ -+ for (; inlen >= ctx->r; inlen -= ctx->r, in += ctx->r) { -+ sha3_fill_state(ctx, in); -+ keccakp_1600(ctx->state); -+ } -+ -+ /* If we have data left, copy it into the partial block buffer */ -+ memcpy(ctx->partial, in, inlen); -+} -+ -+void sha3_final(struct sha_ctx *ctx, uint8_t *digest) -+{ -+ size_t partial = ctx->msg_len % ctx->r; -+ unsigned int i; -+ -+ /* Final round in sponge absorbing phase */ -+ -+ /* Fill the unused part of the partial buffer with zeros */ -+ memset(ctx->partial + partial, 0, ctx->r - partial); -+ -+ /* -+ * Add the leading and trailing bit as well as the 01 bits for the -+ * SHA-3 suffix. -+ */ -+ ctx->partial[partial] = 0x06; -+ ctx->partial[ctx->r - 1] |= 0x80; -+ -+ /* Final transformation */ -+ sha3_fill_state(ctx, ctx->partial); -+ keccakp_1600(ctx->state); -+ -+ /* -+ * Sponge squeeze phase - the digest size is always smaller as the -+ * state size r which implies we only have one squeeze round. -+ */ -+ for (i = 0; i < ctx->digestsize / 8; i++, digest += 8) -+ le64_to_ptr(digest, ctx->state[i]); -+ -+ /* Add remaining 4 bytes if we use SHA3-224 */ -+ if (ctx->digestsize % 8) -+ le32_to_ptr(digest, (uint32_t)(ctx->state[i])); -+ -+ memset(ctx->partial, 0, ctx->r); -+ sha3_init(ctx); -+} -+ -+int sha3_tester(void) -+{ -+ HASH_CTX_ON_STACK(ctx); -+ static const uint8_t msg_256[] = { 0x5E, 0x5E, 0xD6 }; -+ static const uint8_t exp_256[] = { 0xF1, 0x6E, 0x66, 0xC0, 0x43, 0x72, -+ 0xB4, 0xA3, 0xE1, 0xE3, 0x2E, 0x07, -+ 0xC4, 0x1C, 0x03, 0x40, 0x8A, 0xD5, -+ 0x43, 0x86, 0x8C, 0xC4, 0x0E, 0xC5, -+ 0x5E, 0x00, 0xBB, 0xBB, 0xBD, 0xF5, -+ 0x91, 0x1E }; -+ uint8_t act[SHA3_256_SIZE_DIGEST] = { 0 }; -+ unsigned int i; -+ -+ sha3_256_init(&ctx); -+ sha3_update(&ctx, msg_256, 3); -+ sha3_final(&ctx, act); -+ -+ for (i = 0; i < SHA3_256_SIZE_DIGEST; i++) { -+ if (exp_256[i] != act[i]) -+ return 1; -+ } -+ -+ return 0; -+} -Index: libgcrypt-1.9.4/random/jitterentropy-sha3.h -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-sha3.h -@@ -0,0 +1,56 @@ -+/* -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#ifndef JITTERENTROPY_SHA3_H -+#define JITTERENTROPY_SHA3_H -+ -+#include "jitterentropy.h" -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+#define SHA3_SIZE_BLOCK(bits) ((1600 - 2 * bits) >> 3) -+#define SHA3_256_SIZE_BLOCK SHA3_SIZE_BLOCK(SHA3_256_SIZE_DIGEST_BITS) -+#define SHA3_MAX_SIZE_BLOCK SHA3_256_SIZE_BLOCK -+ -+struct sha_ctx { -+ uint64_t state[25]; -+ size_t msg_len; -+ unsigned int r; -+ unsigned int rword; -+ unsigned int digestsize; -+ uint8_t partial[SHA3_MAX_SIZE_BLOCK]; -+}; -+ -+#define SHA_MAX_CTX_SIZE (sizeof(struct sha_ctx)) -+#define HASH_CTX_ON_STACK(name) \ -+ struct sha_ctx name -+ -+void sha3_256_init(struct sha_ctx *ctx); -+void sha3_update(struct sha_ctx *ctx, const uint8_t *in, size_t inlen); -+void sha3_final(struct sha_ctx *ctx, uint8_t *digest); -+int sha3_tester(void); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* JITTERENTROPY_SHA3_H */ -Index: libgcrypt-1.9.4/random/jitterentropy-timer.c -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-timer.c -@@ -0,0 +1,234 @@ -+/* Jitter RNG: Internal timer implementation -+ * -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#include "jitterentropy-base.h" -+#include "jitterentropy-timer.h" -+ -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+ -+/*************************************************************************** -+ * Thread handler -+ ***************************************************************************/ -+ -+JENT_PRIVATE_STATIC -+int jent_notime_init(void **ctx) -+{ -+ struct jent_notime_ctx *thread_ctx; -+ long ncpu = jent_ncpu(); -+ -+ if (ncpu < 0) -+ return (int)ncpu; -+ -+ /* We need at least two CPUs to enable the timer thread */ -+ if (ncpu < 2) -+ return -EOPNOTSUPP; -+ -+ thread_ctx = calloc(1, sizeof(struct jent_notime_ctx)); -+ if (!thread_ctx) -+ return -errno; -+ -+ *ctx = thread_ctx; -+ -+ return 0; -+} -+ -+JENT_PRIVATE_STATIC -+void jent_notime_fini(void *ctx) -+{ -+ struct jent_notime_ctx *thread_ctx = (struct jent_notime_ctx *)ctx; -+ -+ if (thread_ctx) -+ free(thread_ctx); -+} -+ -+static int jent_notime_start(void *ctx, -+ void *(*start_routine) (void *), void *arg) -+{ -+ struct jent_notime_ctx *thread_ctx = (struct jent_notime_ctx *)ctx; -+ int ret; -+ -+ if (!thread_ctx) -+ return -EINVAL; -+ -+ ret = -pthread_attr_init(&thread_ctx->notime_pthread_attr); -+ if (ret) -+ return ret; -+ -+ return -pthread_create(&thread_ctx->notime_thread_id, -+ &thread_ctx->notime_pthread_attr, -+ start_routine, arg); -+} -+ -+static void jent_notime_stop(void *ctx) -+{ -+ struct jent_notime_ctx *thread_ctx = (struct jent_notime_ctx *)ctx; -+ -+ pthread_join(thread_ctx->notime_thread_id, NULL); -+ pthread_attr_destroy(&thread_ctx->notime_pthread_attr); -+} -+ -+static struct jent_notime_thread jent_notime_thread_builtin = { -+ .jent_notime_init = jent_notime_init, -+ .jent_notime_fini = jent_notime_fini, -+ .jent_notime_start = jent_notime_start, -+ .jent_notime_stop = jent_notime_stop -+}; -+ -+/*************************************************************************** -+ * Timer-less timer replacement -+ * -+ * If there is no high-resolution hardware timer available, we create one -+ * ourselves. This logic is only used when the initialization identifies -+ * that no suitable time source is available. -+ ***************************************************************************/ -+ -+static int jent_force_internal_timer = 0; -+static int jent_notime_switch_blocked = 0; -+ -+void jent_notime_block_switch(void) -+{ -+ jent_notime_switch_blocked = 1; -+} -+ -+static struct jent_notime_thread *notime_thread = &jent_notime_thread_builtin; -+ -+/** -+ * Timer-replacement loop -+ * -+ * @brief The measurement loop triggers the read of the value from the -+ * counter function. It conceptually acts as the low resolution -+ * samples timer from a ring oscillator. -+ */ -+static void *jent_notime_sample_timer(void *arg) -+{ -+ struct rand_data *ec = (struct rand_data *)arg; -+ -+ ec->notime_timer = 0; -+ -+ while (1) { -+ if (ec->notime_interrupt) -+ return NULL; -+ -+ ec->notime_timer++; -+ } -+ -+ return NULL; -+} -+ -+/* -+ * Enable the clock: spawn a new thread that holds a counter. -+ * -+ * Note, although creating a thread is expensive, we do that every time a -+ * caller wants entropy from us and terminate the thread afterwards. This -+ * is to ensure an attacker cannot easily identify the ticking thread. -+ */ -+int jent_notime_settick(struct rand_data *ec) -+{ -+ if (!ec->enable_notime || !notime_thread) -+ return 0; -+ -+ ec->notime_interrupt = 0; -+ ec->notime_prev_timer = 0; -+ ec->notime_timer = 0; -+ -+ return notime_thread->jent_notime_start(ec->notime_thread_ctx, -+ jent_notime_sample_timer, ec); -+} -+ -+void jent_notime_unsettick(struct rand_data *ec) -+{ -+ if (!ec->enable_notime || !notime_thread) -+ return; -+ -+ ec->notime_interrupt = 1; -+ notime_thread->jent_notime_stop(ec->notime_thread_ctx); -+} -+ -+void jent_get_nstime_internal(struct rand_data *ec, uint64_t *out) -+{ -+ if (ec->enable_notime) { -+ /* -+ * Allow the counting thread to be initialized and guarantee -+ * that it ticked since last time we looked. -+ * -+ * Note, we do not use an atomic operation here for reading -+ * jent_notime_timer since if this integer is garbled, it even -+ * adds to entropy. But on most architectures, read/write -+ * of an uint64_t should be atomic anyway. -+ */ -+ while (ec->notime_timer == ec->notime_prev_timer) -+ jent_yield(); -+ -+ ec->notime_prev_timer = ec->notime_timer; -+ *out = ec->notime_prev_timer; -+ } else { -+ jent_get_nstime(out); -+ } -+} -+ -+static inline int jent_notime_enable_thread(struct rand_data *ec) -+{ -+ if (notime_thread) -+ return notime_thread->jent_notime_init(&ec->notime_thread_ctx); -+ return 0; -+} -+ -+void jent_notime_disable(struct rand_data *ec) -+{ -+ if (notime_thread) -+ notime_thread->jent_notime_fini(ec->notime_thread_ctx); -+} -+ -+int jent_notime_enable(struct rand_data *ec, unsigned int flags) -+{ -+ /* Use internal timer */ -+ if (jent_force_internal_timer || (flags & JENT_FORCE_INTERNAL_TIMER)) { -+ /* Self test not run yet */ -+ if (!jent_force_internal_timer && -+ jent_time_entropy_init(flags | JENT_FORCE_INTERNAL_TIMER, -+ ec->osr)) -+ return EHEALTH; -+ -+ ec->enable_notime = 1; -+ return jent_notime_enable_thread(ec); -+ } -+ -+ return 0; -+} -+ -+int jent_notime_switch(struct jent_notime_thread *new_thread) -+{ -+ if (jent_notime_switch_blocked) -+ return -EAGAIN; -+ notime_thread = new_thread; -+ return 0; -+} -+ -+void jent_notime_force(void) -+{ -+ jent_force_internal_timer = 1; -+} -+ -+int jent_notime_forced(void) -+{ -+ return jent_force_internal_timer; -+} -+ -+#endif /* JENT_CONF_ENABLE_INTERNAL_TIMER */ -Index: libgcrypt-1.9.4/random/jitterentropy-timer.h -=================================================================== ---- /dev/null -+++ libgcrypt-1.9.4/random/jitterentropy-timer.h -@@ -0,0 +1,92 @@ -+/* -+ * Copyright (C) 2021, Stephan Mueller -+ * -+ * License: see LICENSE file in root directory -+ * -+ * 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. -+ */ -+ -+#ifndef JITTERENTROPY_TIMER_H -+#define JITTERENTROPY_TIMER_H -+ -+#include "jitterentropy.h" -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+ -+void jent_notime_block_switch(void); -+int jent_notime_settick(struct rand_data *ec); -+void jent_notime_unsettick(struct rand_data *ec); -+void jent_get_nstime_internal(struct rand_data *ec, uint64_t *out); -+int jent_notime_enable(struct rand_data *ec, unsigned int flags); -+void jent_notime_disable(struct rand_data *ec); -+int jent_notime_switch(struct jent_notime_thread *new_thread); -+void jent_notime_force(void); -+int jent_notime_forced(void); -+ -+#else /* JENT_CONF_ENABLE_INTERNAL_TIMER */ -+ -+static inline void jent_notime_block_switch(void) { } -+ -+static inline int jent_notime_settick(struct rand_data *ec) -+{ -+ (void)ec; -+ return 0; -+} -+ -+static inline void jent_notime_unsettick(struct rand_data *ec) { (void)ec; } -+ -+static inline void jent_get_nstime_internal(struct rand_data *ec, uint64_t *out) -+{ -+ (void)ec; -+ jent_get_nstime(out); -+} -+ -+static inline int jent_notime_enable(struct rand_data *ec, unsigned int flags) -+{ -+ (void)ec; -+ -+ /* If we force the timer-less noise source, we return an error */ -+ if (flags & JENT_FORCE_INTERNAL_TIMER) -+ return EHEALTH; -+ -+ return 0; -+} -+ -+static inline void jent_notime_disable(struct rand_data *ec) -+{ -+ (void)ec; -+} -+ -+static inline int jent_notime_switch(struct jent_notime_thread *new_thread) -+{ -+ (void)new_thread; -+ return -EOPNOTSUPP; -+} -+ -+static inline void jent_notime_force(void) { } -+ -+static inline int jent_notime_forced(void) { return 0; } -+ -+#endif /* JENT_CONF_ENABLE_INTERNAL_TIMER */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* JITTERENTROPY-TIMER_H */ -Index: libgcrypt-1.9.4/random/Makefile.am -=================================================================== ---- libgcrypt-1.9.4.orig/random/Makefile.am -+++ libgcrypt-1.9.4/random/Makefile.am -@@ -50,9 +50,14 @@ rndegd.c \ - rndunix.c \ - rndw32.c \ - rndw32ce.c \ -+jitterentropy-gcd.c jitterentropy-gcd.h \ -+jitterentropy-health.c jitterentropy-health.h \ -+jitterentropy-noise.c jitterentropy-noise.h \ -+jitterentropy-sha3.c jitterentropy-sha3.h \ -+jitterentropy-timer.c jitterentropy-timer.h \ -+jitterentropy-base.h \ - jitterentropy-base.c jitterentropy.h jitterentropy-base-user.h - -- - # The rndjent module needs to be compiled without optimization. */ - if ENABLE_O_FLAG_MUNGING - o_flag_munging = sed -e 's/-O\([1-9sg][1-9sg]*\)/-O0/g' -e 's/-Ofast/-O0/g' -@@ -61,9 +66,19 @@ o_flag_munging = cat - endif - - rndjent.o: $(srcdir)/rndjent.c jitterentropy-base-user.h \ -+ $(srcdir)/jitterentropy-gcd.c $(srcdir)/jitterentropy-gcd.h \ -+ $(srcdir)/jitterentropy-health.c $(srcdir)/jitterentropy-health.h \ -+ $(srcdir)/jitterentropy-noise.c $(srcdir)/jitterentropy-noise.h \ -+ $(srcdir)/jitterentropy-sha3.c $(srcdir)/jitterentropy-sha3.h \ -+ $(srcdir)/jitterentropy-timer.c $(srcdir)/jitterentropy-timer.h \ - $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h - `echo $(COMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) ` - - rndjent.lo: $(srcdir)/rndjent.c jitterentropy-base-user.h \ -+ $(srcdir)/jitterentropy-gcd.c $(srcdir)/jitterentropy-gcd.h \ -+ $(srcdir)/jitterentropy-health.c $(srcdir)/jitterentropy-health.h \ -+ $(srcdir)/jitterentropy-noise.c $(srcdir)/jitterentropy-noise.h \ -+ $(srcdir)/jitterentropy-sha3.c $(srcdir)/jitterentropy-sha3.h \ -+ $(srcdir)/jitterentropy-timer.c $(srcdir)/jitterentropy-timer.h \ - $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h - `echo $(LTCOMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) ` -Index: libgcrypt-1.9.4/random/Makefile.in -=================================================================== ---- libgcrypt-1.9.4.orig/random/Makefile.in -+++ libgcrypt-1.9.4/random/Makefile.in -@@ -156,6 +156,11 @@ am__depfiles_remade = ./$(DEPDIR)/jitter - ./$(DEPDIR)/random-csprng.Plo ./$(DEPDIR)/random-daemon.Plo \ - ./$(DEPDIR)/random-drbg.Plo ./$(DEPDIR)/random-system.Plo \ - ./$(DEPDIR)/random.Plo ./$(DEPDIR)/rndegd.Plo \ -+ ./$(DEPDIR)/jitterentropy-gcd.Plo \ -+ ./$(DEPDIR)/jitterentropy-health.Plo \ -+ ./$(DEPDIR)/jitterentropy-noise.Plo \ -+ ./$(DEPDIR)/jitterentropy-sha3.Plo \ -+ ./$(DEPDIR)/jitterentropy-timer.Plo \ - ./$(DEPDIR)/rndhw.Plo ./$(DEPDIR)/rndjent.Plo \ - ./$(DEPDIR)/rndlinux.Plo ./$(DEPDIR)/rndunix.Plo \ - ./$(DEPDIR)/rndw32.Plo ./$(DEPDIR)/rndw32ce.Plo -@@ -391,6 +396,12 @@ rndegd.c \ - rndunix.c \ - rndw32.c \ - rndw32ce.c \ -+jitterentropy-gcd.c jitterentropy-gcd.h \ -+jitterentropy-health.c jitterentropy-health.h \ -+jitterentropy-noise.c jitterentropy-noise.h \ -+jitterentropy-sha3.c jitterentropy-sha3.h \ -+jitterentropy-timer.c jitterentropy-timer.h \ -+jitterentropy-base.h \ - jitterentropy-base.c jitterentropy.h jitterentropy-base-user.h - - @ENABLE_O_FLAG_MUNGING_FALSE@o_flag_munging = cat -@@ -452,6 +463,11 @@ distclean-compile: - -rm -f *.tab.c - - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jitterentropy-base.Plo@am__quote@ # am--include-marker -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jitterentropy-gcd.Plo@am__quote@ # am--include-marker -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jitterentropy-health.Plo@am__quote@ # am--include-marker -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jitterentropy-noise.Plo@am__quote@ # am--include-marker -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jitterentropy-sha3.Plo@am__quote@ # am--include-marker -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jitterentropy-timer.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-csprng.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-daemon.Plo@am__quote@ # am--include-marker - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-drbg.Plo@am__quote@ # am--include-marker -@@ -624,6 +640,11 @@ clean-am: clean-generic clean-libtool cl - - distclean: distclean-am - -rm -f ./$(DEPDIR)/jitterentropy-base.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-gcd.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-health.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-noise.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-sha3.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-timer.Plo - -rm -f ./$(DEPDIR)/random-csprng.Plo - -rm -f ./$(DEPDIR)/random-daemon.Plo - -rm -f ./$(DEPDIR)/random-drbg.Plo -@@ -682,6 +703,11 @@ installcheck-am: - - maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/jitterentropy-base.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-gcd.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-health.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-noise.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-sha3.Plo -+ -rm -f ./$(DEPDIR)/jitterentropy-timer.Plo - -rm -f ./$(DEPDIR)/random-csprng.Plo - -rm -f ./$(DEPDIR)/random-daemon.Plo - -rm -f ./$(DEPDIR)/random-drbg.Plo -@@ -732,10 +758,20 @@ uninstall-am: - - - rndjent.o: $(srcdir)/rndjent.c jitterentropy-base-user.h \ -+ $(srcdir)/jitterentropy-gcd.c $(srcdir)/jitterentropy-gcd.h \ -+ $(srcdir)/jitterentropy-health.c $(srcdir)/jitterentropy-health.h \ -+ $(srcdir)/jitterentropy-noise.c $(srcdir)/jitterentropy-noise.h \ -+ $(srcdir)/jitterentropy-sha3.c $(srcdir)/jitterentropy-sha3.h \ -+ $(srcdir)/jitterentropy-timer.c $(srcdir)/jitterentropy-timer.h \ - $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h - `echo $(COMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) ` - - rndjent.lo: $(srcdir)/rndjent.c jitterentropy-base-user.h \ -+ $(srcdir)/jitterentropy-gcd.c $(srcdir)/jitterentropy-gcd.h \ -+ $(srcdir)/jitterentropy-health.c $(srcdir)/jitterentropy-health.h \ -+ $(srcdir)/jitterentropy-noise.c $(srcdir)/jitterentropy-noise.h \ -+ $(srcdir)/jitterentropy-sha3.c $(srcdir)/jitterentropy-sha3.h \ -+ $(srcdir)/jitterentropy-timer.c $(srcdir)/jitterentropy-timer.h \ - $(srcdir)/jitterentropy-base.c $(srcdir)/jitterentropy.h - `echo $(LTCOMPILE) -c $(srcdir)/rndjent.c | $(o_flag_munging) ` - -Index: libgcrypt-1.9.4/random/random-csprng.c -=================================================================== ---- libgcrypt-1.9.4.orig/random/random-csprng.c -+++ libgcrypt-1.9.4/random/random-csprng.c -@@ -357,6 +357,17 @@ _gcry_rngcsprng_close_fds (void) - _gcry_rndlinux_gather_random (NULL, 0, 0, 0); - pool_filled = 0; /* Force re-open on next use. */ - #endif -+ pool_writepos = 0; -+ pool_readpos = 0; -+ pool_filled = 0; -+ pool_filled_counter = 0; -+ did_initial_extra_seeding = 0; -+ pool_balance = 0; -+ just_mixed = 0; -+ xfree (rndpool); -+ xfree (keypool); -+ rndpool = NULL; -+ keypool = NULL; - unlock_pool (); - } - -Index: libgcrypt-1.9.4/random/random-drbg.c -=================================================================== ---- libgcrypt-1.9.4.orig/random/random-drbg.c -+++ libgcrypt-1.9.4/random/random-drbg.c -@@ -1860,16 +1860,23 @@ _gcry_rngdrbg_reinit (const char *flagst - return ret; - } - --/* Try to close the FDs of the random gather module. This is -- * currently only implemented for rndlinux. */ -+/* Release resources used by this DRBG module. That is, close the FDs -+ * of the random gather module (if any), and release memory used. -+ */ - void - _gcry_rngdrbg_close_fds (void) - { --#if USE_RNDLINUX - drbg_lock (); -+#if USE_RNDLINUX - _gcry_rndlinux_gather_random (NULL, 0, 0, 0); -- drbg_unlock (); - #endif -+ if (drbg_state) -+ { -+ drbg_uninstantiate (drbg_state); -+ xfree (drbg_state); -+ drbg_state = NULL; -+ } -+ drbg_unlock (); - } - - /* Print some statistics about the RNG. */ -Index: libgcrypt-1.9.4/random/rndjent.c -=================================================================== ---- libgcrypt-1.9.4.orig/random/rndjent.c -+++ libgcrypt-1.9.4/random/rndjent.c -@@ -43,6 +43,8 @@ - #ifdef HAVE_STDINT_H - # include - #endif -+#include -+#include - - #include "types.h" - #include "g10lib.h" -@@ -84,7 +86,14 @@ - #define JENT_PRIVATE_COMPILE 1 - - #include "jitterentropy-base.c" -- -+#ifdef JENT_CONF_ENABLE_INTERNAL_TIMER -+#include -+#endif /* JENT_CONF_ENABLE_INTERNAL_TIMER */ -+#include "jitterentropy-gcd.c" -+#include "jitterentropy-health.c" -+#include "jitterentropy-noise.c" -+#include "jitterentropy-sha3.c" -+#include "jitterentropy-timer.c" - - /* This is the lock we use to serialize access to this RNG. The extra - * integer variable is only used to check the locking state; that is, -@@ -291,7 +300,7 @@ _gcry_rndjent_poll (void (*add)(const vo - size_t n = length < sizeof(buffer)? length : sizeof (buffer); - - jent_rng_totalcalls++; -- rc = jent_read_entropy (jent_rng_collector, buffer, n); -+ rc = jent_read_entropy_safe (&jent_rng_collector, buffer, n); - if (rc < 0) - break; - /* We need to hash the output to conform to the BSI diff --git a/libgcrypt-jitterentropy-3.4.0.patch b/libgcrypt-jitterentropy-3.4.0.patch index 997ef2a..dbb77ba 100644 --- a/libgcrypt-jitterentropy-3.4.0.patch +++ b/libgcrypt-jitterentropy-3.4.0.patch @@ -1,7 +1,7 @@ -Index: libgcrypt-1.9.4/random/jitterentropy-base.c +Index: libgcrypt-1.10.0/random/jitterentropy-base.c =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-base.c -+++ libgcrypt-1.9.4/random/jitterentropy-base.c +--- libgcrypt-1.10.0.orig/random/jitterentropy-base.c ++++ libgcrypt-1.10.0/random/jitterentropy-base.c @@ -42,7 +42,7 @@ * require consumer to be updated (as long as this number * is zero, the API is not considered stable and can @@ -145,10 +145,10 @@ Index: libgcrypt-1.9.4/random/jitterentropy-base.c +{ + return jent_set_fips_failure_callback_internal(cb); +} -Index: libgcrypt-1.9.4/random/jitterentropy-gcd.c +Index: libgcrypt-1.10.0/random/jitterentropy-gcd.c =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-gcd.c -+++ libgcrypt-1.9.4/random/jitterentropy-gcd.c +--- libgcrypt-1.10.0.orig/random/jitterentropy-gcd.c ++++ libgcrypt-1.10.0/random/jitterentropy-gcd.c @@ -113,12 +113,8 @@ int jent_gcd_analyze(uint64_t *delta_his goto out; } @@ -164,10 +164,10 @@ Index: libgcrypt-1.9.4/random/jitterentropy-gcd.c ret = ECOARSETIME; goto out; } -Index: libgcrypt-1.9.4/random/jitterentropy-health.c +Index: libgcrypt-1.10.0/random/jitterentropy-health.c =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-health.c -+++ libgcrypt-1.9.4/random/jitterentropy-health.c +--- libgcrypt-1.10.0.orig/random/jitterentropy-health.c ++++ libgcrypt-1.10.0/random/jitterentropy-health.c @@ -19,9 +19,24 @@ * DAMAGE. */ @@ -204,10 +204,10 @@ Index: libgcrypt-1.9.4/random/jitterentropy-health.c + return ec->health_failure; } -Index: libgcrypt-1.9.4/random/jitterentropy-health.h +Index: libgcrypt-1.10.0/random/jitterentropy-health.h =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-health.h -+++ libgcrypt-1.9.4/random/jitterentropy-health.h +--- libgcrypt-1.10.0.orig/random/jitterentropy-health.h ++++ libgcrypt-1.10.0/random/jitterentropy-health.h @@ -20,11 +20,16 @@ #ifndef JITTERENTROPY_HEALTH_H #define JITTERENTROPY_HEALTH_H @@ -225,10 +225,10 @@ Index: libgcrypt-1.9.4/random/jitterentropy-health.h static inline uint64_t jent_delta(uint64_t prev, uint64_t next) { return (next - prev); -Index: libgcrypt-1.9.4/random/jitterentropy-noise.c +Index: libgcrypt-1.10.0/random/jitterentropy-noise.c =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-noise.c -+++ libgcrypt-1.9.4/random/jitterentropy-noise.c +--- libgcrypt-1.10.0.orig/random/jitterentropy-noise.c ++++ libgcrypt-1.10.0/random/jitterentropy-noise.c @@ -33,7 +33,7 @@ * Update of the loop count used for the next round of * an entropy collection. @@ -459,10 +459,10 @@ Index: libgcrypt-1.9.4/random/jitterentropy-noise.c + sha3_update(ec->hash_state, jent_block, sizeof(jent_block)); + jent_memset_secure(jent_block, sizeof(jent_block)); +} -Index: libgcrypt-1.9.4/random/jitterentropy-noise.h +Index: libgcrypt-1.10.0/random/jitterentropy-noise.h =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-noise.h -+++ libgcrypt-1.9.4/random/jitterentropy-noise.h +--- libgcrypt-1.10.0.orig/random/jitterentropy-noise.h ++++ libgcrypt-1.10.0/random/jitterentropy-noise.h @@ -31,6 +31,7 @@ unsigned int jent_measure_jitter(struct uint64_t loop_cnt, uint64_t *ret_current_delta); @@ -471,10 +471,10 @@ Index: libgcrypt-1.9.4/random/jitterentropy-noise.h #ifdef __cplusplus } -Index: libgcrypt-1.9.4/random/jitterentropy-sha3.c +Index: libgcrypt-1.10.0/random/jitterentropy-sha3.c =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-sha3.c -+++ libgcrypt-1.9.4/random/jitterentropy-sha3.c +--- libgcrypt-1.10.0.orig/random/jitterentropy-sha3.c ++++ libgcrypt-1.10.0/random/jitterentropy-sha3.c @@ -19,6 +19,7 @@ */ @@ -507,10 +507,10 @@ Index: libgcrypt-1.9.4/random/jitterentropy-sha3.c + + jent_zfree(ctx, SHA_MAX_CTX_SIZE); +} -Index: libgcrypt-1.9.4/random/jitterentropy-sha3.h +Index: libgcrypt-1.10.0/random/jitterentropy-sha3.h =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-sha3.h -+++ libgcrypt-1.9.4/random/jitterentropy-sha3.h +--- libgcrypt-1.10.0.orig/random/jitterentropy-sha3.h ++++ libgcrypt-1.10.0/random/jitterentropy-sha3.h @@ -47,6 +47,8 @@ struct sha_ctx { void sha3_256_init(struct sha_ctx *ctx); void sha3_update(struct sha_ctx *ctx, const uint8_t *in, size_t inlen); @@ -520,10 +520,10 @@ Index: libgcrypt-1.9.4/random/jitterentropy-sha3.h int sha3_tester(void); #ifdef __cplusplus -Index: libgcrypt-1.9.4/random/jitterentropy-timer.c +Index: libgcrypt-1.10.0/random/jitterentropy-timer.c =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-timer.c -+++ libgcrypt-1.9.4/random/jitterentropy-timer.c +--- libgcrypt-1.10.0.orig/random/jitterentropy-timer.c ++++ libgcrypt-1.10.0/random/jitterentropy-timer.c @@ -202,8 +202,8 @@ int jent_notime_enable(struct rand_data if (jent_force_internal_timer || (flags & JENT_FORCE_INTERNAL_TIMER)) { /* Self test not run yet */ @@ -535,10 +535,10 @@ Index: libgcrypt-1.9.4/random/jitterentropy-timer.c return EHEALTH; ec->enable_notime = 1; -Index: libgcrypt-1.9.4/random/jitterentropy.h +Index: libgcrypt-1.10.0/random/jitterentropy.h =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy.h -+++ libgcrypt-1.9.4/random/jitterentropy.h +--- libgcrypt-1.10.0.orig/random/jitterentropy.h ++++ libgcrypt-1.10.0/random/jitterentropy.h @@ -49,7 +49,7 @@ ***************************************************************************/ @@ -557,7 +557,7 @@ Index: libgcrypt-1.9.4/random/jitterentropy.h uint64_t prev_time; /* SENSITIVE Previous time stamp */ #define DATA_SIZE_BITS (SHA3_256_SIZE_DIGEST_BITS) -@@ -378,28 +379,34 @@ int jent_entropy_init(void); +@@ -378,28 +378,34 @@ int jent_entropy_init(void); JENT_PRIVATE_STATIC int jent_entropy_init_ex(unsigned int osr, unsigned int flags); @@ -597,11 +597,11 @@ Index: libgcrypt-1.9.4/random/jitterentropy.h JENT_PRIVATE_STATIC int jent_notime_init(void **ctx); -Index: libgcrypt-1.9.4/random/jitterentropy-base-user.h +Index: libgcrypt-1.10.0/random/jitterentropy-base-user.h =================================================================== ---- libgcrypt-1.9.4.orig/random/jitterentropy-base-user.h -+++ libgcrypt-1.9.4/random/jitterentropy-base-user.h -@@ -216,12 +216,12 @@ static inline void jent_get_cachesize(lo +--- libgcrypt-1.10.0.orig/random/jitterentropy-base-user.h ++++ libgcrypt-1.10.0/random/jitterentropy-base-user.h +@@ -213,12 +213,12 @@ static inline void jent_get_cachesize(lo ext = strstr(buf, "K"); if (ext) { shift = 10; diff --git a/libgcrypt-pthread-in-t-lock-test.patch b/libgcrypt-pthread-in-t-lock-test.patch deleted file mode 100644 index da1a602..0000000 --- a/libgcrypt-pthread-in-t-lock-test.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: libgcrypt-1.9.3/tests/Makefile.am -=================================================================== ---- libgcrypt-1.9.3.orig/tests/Makefile.am -+++ libgcrypt-1.9.3/tests/Makefile.am -@@ -74,7 +74,7 @@ prime_LDADD = $(standard_ldadd) @LDADD_F - t_mpi_bit_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@ - t_secmem_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@ - testapi_LDADD = $(standard_ldadd) @LDADD_FOR_TESTS_KLUDGE@ --t_lock_LDADD = $(standard_ldadd) $(GPG_ERROR_MT_LIBS) @LDADD_FOR_TESTS_KLUDGE@ -+t_lock_LDADD = $(standard_ldadd) $(GPG_ERROR_MT_LIBS) -lpthread @LDADD_FOR_TESTS_KLUDGE@ - t_lock_CFLAGS = $(GPG_ERROR_MT_CFLAGS) - testdrv_LDADD = $(LDADD_FOR_TESTS_KLUDGE) - diff --git a/libgcrypt-random_selftests-testentropy.patch b/libgcrypt-random_selftests-testentropy.patch deleted file mode 100644 index b56b756..0000000 --- a/libgcrypt-random_selftests-testentropy.patch +++ /dev/null @@ -1,15 +0,0 @@ -Index: libgcrypt-1.8.2/random/random-drbg.c -=================================================================== ---- libgcrypt-1.8.2.orig/random/random-drbg.c -+++ libgcrypt-1.8.2/random/random-drbg.c -@@ -2428,6 +2428,10 @@ drbg_healthcheck_sanity (struct gcry_drb - - /* if the following tests fail, it is likely that there is a buffer - * overflow and we get a SIGSEV */ -+ test_data.testentropy = &testentropy; -+ test_data.fail_seed_source = 0; -+ drbg_string_fill (&testentropy, test->entropy, test->entropylen); -+ drbg->test_data = &test_data; - ret = drbg_instantiate (drbg, NULL, coreref, 1); - if (ret) - goto outbuf; diff --git a/libgcrypt-rsa-no-blinding.patch b/libgcrypt-rsa-no-blinding.patch deleted file mode 100644 index a396504..0000000 --- a/libgcrypt-rsa-no-blinding.patch +++ /dev/null @@ -1,92 +0,0 @@ ---- libgcrypt-1.8.2.orig/cipher/rsa.c 2020-03-26 07:23:17.392861551 +0100 -+++ libgcrypt-1.8.2.orig/cipher/rsa.c 2020-03-26 15:43:29.556282072 +0100 -@@ -91,10 +91,16 @@ static const char sample_secret_key[] = - " 79C974A6FA69E4D52FE796650623DE70622862713932AA2FD9F2EC856EAEAA77" - " 88B4EA6084DC81C902F014829B18EA8B2666EC41586818E0589E18876065F97E" - " 8D22CE2DA53A05951EC132DCEF41E70A9C35F4ACC268FFAC2ADF54FA1DA110B919#)" -+"))"; -+/* We need to get rid of the u value, in order to end in -+ * secret_core_std when called from secret. It's not used anyway. */ -+ -+/* - " (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04" - " 479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4" - " A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9" - " AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7#)))"; -+*/ - - /* A sample 2048 bit RSA key used for the selftests (public only). */ - static const char sample_public_key[] = -@@ -1252,8 +1258,8 @@ rsa_check_secret_key (gcry_sexp_t keypar - RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL}; - - /* To check the key we need the optional parameters. */ -- rc = sexp_extract_param (keyparms, NULL, "nedpqu", -- &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u, -+ rc = sexp_extract_param (keyparms, NULL, "npq", -+ &sk.n, &sk.p, &sk.q, - NULL); - if (rc) - goto leave; -@@ -1263,11 +1269,8 @@ rsa_check_secret_key (gcry_sexp_t keypar - - leave: - _gcry_mpi_release (sk.n); -- _gcry_mpi_release (sk.e); -- _gcry_mpi_release (sk.d); - _gcry_mpi_release (sk.p); - _gcry_mpi_release (sk.q); -- _gcry_mpi_release (sk.u); - if (DBG_CIPHER) - log_debug ("rsa_testkey => %s\n", gpg_strerror (rc)); - return rc; -@@ -1710,11 +1713,11 @@ static const char * - selftest_sign_2048 (gcry_sexp_t pkey, gcry_sexp_t skey) - { - static const char sample_data[] = -- "(data (flags pkcs1)" -+ "(data (flags pkcs1 no-blinding)" - " (hash sha256 #11223344556677889900aabbccddeeff" - /**/ "102030405060708090a0b0c0d0f01121#))"; - static const char sample_data_bad[] = -- "(data (flags pkcs1)" -+ "(data (flags pkcs1 no-blinding)" - " (hash sha256 #11223344556677889900aabbccddeeff" - /**/ "802030405060708090a0b0c0d0f01121#))"; - -@@ -1857,7 +1860,7 @@ selftest_encr_2048 (gcry_sexp_t pkey, gc - gcry_mpi_t ref_mpi = NULL; - - /* Put the plaintext into an S-expression. */ -- err = sexp_build (&plain, NULL, "(data (flags raw) (value %s))", plaintext); -+ err = sexp_build (&plain, NULL, "(data (flags raw no-blinding) (value %s))", plaintext); - if (err) - { - errtxt = "converting data failed"; -@@ -1897,6 +1900,26 @@ selftest_encr_2048 (gcry_sexp_t pkey, gc - goto leave; - } - -+ /* This sexp trickery is to prevent the use of blinding. -+ * The flag doesn't get inherited by encr, so we have to -+ * derive a new sexp from the ciphertext */ -+ char buf[1024]; -+ memset(buf, 0, sizeof(buf)); -+ err = _gcry_mpi_print (GCRYMPI_FMT_STD, buf, sizeof buf, NULL, ciphertext); -+ if (err) -+ { -+ errtxt = "Dumping ciphertext mpi to buffer failed"; -+ goto leave; -+ } -+ -+ sexp_release (encr); -+ err = sexp_build (&encr, NULL, "(enc-val (flags no-blinding) (rsa (a %s)))", buf); -+ if (err) -+ { -+ errtxt = "Adding no-blinding flag to ciphertext failed"; -+ goto leave; -+ } -+ - /* Decrypt. */ - err = _gcry_pk_decrypt (&decr, encr, skey); - if (err) diff --git a/libgcrypt.changes b/libgcrypt.changes index 1ab7201..db5ad97 100644 --- a/libgcrypt.changes +++ b/libgcrypt.changes @@ -1,3 +1,138 @@ +------------------------------------------------------------------- +Wed Oct 19 14:01:24 UTC 2022 - Pedro Monreal + +- Update to 1.10.1: + * Bug fixes: + - Fix minor memory leaks in FIPS mode. + - Build fixes for MUSL libc. + * Other: + - More portable integrity check in FIPS mode. + - Add X9.62 OIDs to sha256 and sha512 modules. + * Add the hardware optimizations config file hwf.deny to + the /etc/gcrypt/ directory. This file can be used to globally + disable the use of hardware based optimizations. + * Remove not needed separate_hmac256_binary hmac256 package + +------------------------------------------------------------------- +Wed Sep 14 13:34:13 UTC 2022 - Pedro Monreal + +- Update to 1.10.0: + * New and extended interfaces: + - New control codes to check for FIPS 140-3 approved algorithms. + - New control code to switch into non-FIPS mode. + - New cipher modes SIV and GCM-SIV as specified by RFC-5297. + - Extended cipher mode AESWRAP with padding as specified by + RFC-5649. + - New set of KDF functions. + - New KDF modes Argon2 and Balloon. + - New functions for combining hashing and signing/verification. + * Performance: + - Improved support for PowerPC architectures. + - Improved ECC performance on zSeries/s390x by using accelerated + scalar multiplication. + - Many more assembler performance improvements for several + architectures. + * Bug fixes: + - Fix Elgamal encryption for other implementations. + [bsc#1190239, CVE-2021-40528] + - Check the input length of the point in ECDH. + - Fix an abort in gcry_pk_get_param for "Curve25519". + * Other features: + - The control code GCRYCTL_SET_ENFORCED_FIPS_FLAG is ignored + because it is useless with the FIPS 140-3 related changes. + - Update of the jitter entropy RNG code. + - Simplification of the entropy gatherer when using the getentropy + system call. + * Interface changes relative to the 1.10.0 release: + - GCRYCTL_SET_DECRYPTION_TAG NEW control code. + - GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER NEW control code. + - GCRYCTL_FIPS_SERVICE_INDICATOR_KDF NEW control code. + - GCRYCTL_NO_FIPS_MODE = 83 NEW control code. + - GCRY_CIPHER_MODE_SIV NEW mode. + - GCRY_CIPHER_MODE_GCM_SIV NEW mode. + - GCRY_CIPHER_EXTENDED NEW flag. + - GCRY_SIV_BLOCK_LEN NEW macro. + - gcry_cipher_set_decryption_tag NEW macro. + - GCRY_KDF_ARGON2 NEW constant. + - GCRY_KDF_BALLOON NEW constant. + - GCRY_KDF_ARGON2D NEW constant. + - GCRY_KDF_ARGON2I NEW constant. + - GCRY_KDF_ARGON2ID NEW constant. + - gcry_kdf_hd_t NEW type. + - gcry_kdf_job_fn_t NEW type. + - gcry_kdf_dispatch_job_fn_t NEW type. + - gcry_kdf_wait_all_jobs_fn_t NEW type. + - struct gcry_kdf_thread_ops NEW struct. + - gcry_kdf_open NEW function. + - gcry_kdf_compute NEW function. + - gcry_kdf_final NEW function. + - gcry_kdf_close NEW function. + - gcry_pk_hash_sign NEW function. + - gcry_pk_hash_verify NEW function. + - gcry_pk_random_override_new NEW function. + * Rebase libgcrypt-1.8.4-allow_FSM_same_state.patch and rename + to libgcrypt-1.10.0-allow_FSM_same_state.patch + * Remove unused CAVS tests and related patches: + - cavs_driver.pl cavs-test.sh + - libgcrypt-1.6.1-fips-cavs.patch + - drbg_test.patch + * Remove DSA sign/verify patches for the FIPS CAVS test since DSA + has been disabled in FIPS mode: + - libgcrypt-fipsdrv-enable-algo-for-dsa-sign.patch + - libgcrypt-fipsdrv-enable-algo-for-dsa-verify.patch + * Rebase libgcrypt-FIPS-SLI-pk.patch + * Rebase libgcrypt_indicators_changes.patch and + libgcrypt-indicate-shake.patch and merge both into + libgcrypt-FIPS-SLI-hash-mac.patch + * Rebase libgcrypt-FIPS-kdf-leylength.patch and rename to + libgcrypt-FIPS-SLI-kdf-leylength.patch + * Rebase libgcrypt-jitterentropy-3.4.0.patch + * Rebase libgcrypt-FIPS-rndjent_poll.patch + * Rebase libgcrypt-out-of-core-handler.patch and rename to + libgcrypt-1.10.0-out-of-core-handler.patch + * Since the FIPS .hmac file is now calculated with the internal + tool hmac256, only the "module is complete" trigger .fips file + is checked. Rename libgcrypt-1.6.1-use-fipscheck.patch + to libgcrypt-1.10.0-use-fipscheck.patch + * Remove patches fixed upstream: + - libgcrypt-1.10.0-rijndael_no_strict_aliasing.patch + - libgcrypt-1.5.0-LIBGCRYPT_FORCE_FIPS_MODE-env.diff + - libgcrypt-fix-rng.patch + - libgcrypt-1.8.3-fips-ctor.patch + - libgcrypt-1.8.4-use_xfree.patch + - libgcrypt-1.8.4-getrandom.patch + - libgcrypt-1.8.4-fips_ctor_skip_integrity_check.patch + - libgcrypt-dsa-rfc6979-test-fix.patch + - libgcrypt-fix-tests-fipsmode.patch + - libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch + - libgcrypt-1.8.4-fips-keygen.patch + - libgcrypt-invoke-global_init-from-constructor.patch + - libgcrypt-Restore-self-tests-from-constructor.patch + - libgcrypt-FIPS-GMAC_AES-benckmark.patch + - libgcrypt-global_init-constructor.patch + - libgcrypt-random_selftests-testentropy.patch + - libgcrypt-rsa-no-blinding.patch + - libgcrypt-ecc-ecdsa-no-blinding.patch + - libgcrypt-PCT-DSA.patch + - libgcrypt-PCT-ECC.patch + - libgcrypt-PCT-RSA.patch + - libgcrypt-fips_selftest_trigger_file.patch + - libgcrypt-pthread-in-t-lock-test.patch + - libgcrypt-FIPS-hw-optimizations.patch + - libgcrypt-FIPS-module-version.patch + - libgcrypt-FIPS-disable-3DES.patch + - libgcrypt-FIPS-fix-regression-tests.patch + - libgcrypt-FIPS-RSA-keylen.patch + - libgcrypt-FIPS-RSA-keylen-tests.patch + - libgcrypt-FIPS-fix-gcry_mpi_sub_ui.patch + - libgcrypt-FIPS-verify-unsupported-KDF-test.patch + - libgcrypt-FIPS-HMAC-short-keylen.patch + - libgcrypt-FIPS-service-indicators.patch + - libgcrypt-FIPS-disable-DSA.patch + - libgcrypt-jitterentropy-3.3.0.patch + - libgcrypt-FIPS-Zeroize-hmac.patch + * Update libgcrypt.keyring + ------------------------------------------------------------------- Thu Sep 8 10:34:53 UTC 2022 - Pedro Monreal diff --git a/libgcrypt.keyring b/libgcrypt.keyring index 96f1bf5..dd3bb0b 100644 --- a/libgcrypt.keyring +++ b/libgcrypt.keyring @@ -1,65 +1,86 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -mQENBE0ti4EBCACqGtKlX9jI/enhlBdy2cyQP6Q7JoyxtaG6/ckAKWHYrqFTQk3I -Ue8TuDrGT742XFncG9PoMBfJDUNltIPgKFn8E9tYQqAOlpSA25bOb30cA2ADkrjg -jvDAH8cZ+fkIayWtObTxwqLfPivjFxEM//IdShFFVQj+QHmXYBJggWyEIil8Bje7 -KRw6B5ucs4qSzp5VH4CqDr9PDnLD8lBGHk0x8jpwh4V/yEODJKATY0Vj00793L8u -qA35ZiyczUvvJSLYvf7STO943GswkxdAfqxXbYifiK2gjE/7SAmB+2jFxsonUDOB -1BAY5s3FKqrkaxZr3BBjeuGGoCuiSX/cXRIhABEBAAG0Fldlcm5lciBLb2NoIChk -aXN0IHNpZymJAVUEEwEIAD8CGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAFiEE -2GkhI8QGXepeDzq1JJs50k8l47YFAl4MxBkFCRShVzYACgkQJJs50k8l47YImQf9 -HaqHWor+aSmaEwQnaAN0zRa4kPbAWya182aJtsFzLZJf6BbS0aoiMhwtREN/DMvB -jzxARKep/cELaM+mc7oDK4mEwqSX/u6BE8D7FaNA9sut8P+4xjpoLPU+UzILMg29 -t1remjyT9rs6sbu8BqufIxueArkjoi4WCOSRiVTdw+YDd88volPkXlPfS8hg9Rct -wZ8kEEDywa+NrxiLx+kDgDNTNdk3PJdfcnesf8S1a+KLUTNRds5+xGTYz0JSQ9BZ -7Q9r4VQ/NL55muQZi5W7lVxdp3HxQFUNjHzzBfGtkpS4xqZpJvNjW50Wh5Vi5RYZ -LZ3M1EuIHXHmRiY4dmqqcpkBDQRUUDsjAQgA5hBwN9F3OqKf+9mXCXUDK4lb5wMj -dti96xG04gAn7wWo7On6c5ntriZQuRdR5GHcdw73XC6CFehHeo/eSVYiWqBNBAfE -9UzbkES+cY+4wDzqVacqhKxd70XmHQgyK7ppRG/MwkL1UyArCGGAKN6MV/2fzO6I -GQw3jntRue3/2PGGnGaisNAKlvttHWZ91uy4KY5fBM19uQCgZdx4v8/rP0+yQqsW -TwJUKvymx5GIfNaCJvgF+v+aPrwspxBMf9jpHXqDXnh4Lo8C/GsQMD6GClVfQjsv -vzUHKH2eoL4oNfku+Ua5BuAHYi+uAuzqV9TdpF9PCpQMyPfuuZclMPLdMwARAQAB -tDJOSUlCRSBZdXRha2EgKEdudVBHIFJlbGVhc2UgS2V5KSA8Z25paWJlQGZzaWou -b3JnPokBPAQTAQgAJgIbAwULBwgJAwQVCAkKBRYCAwEAAh4BAheABQJYDxRZBQkL -S5A2AAoJECBxsIozvT8GvG8IAMBIlGz9voYcSSXAdQOuvz2gM2kOjvMHzN6VlS9V -P06IjnTz2DnejFZwLmxJw8e8mZjUo0jw22uo1HREQhDrne3S1IazPMeTUCUNzpWF -MxXNc6SAyrw9apWa8gouGUWJv3HOwVs8EFA2E9UdtDJ2uG7MY/+eC5K/aeOAyudZ -EbvS8rgZypTFrBtBcNKUWZhz7FRn63HxEmYLE3p6I19ZDXrc1WTazF2oz18zym6c -uURr6waRbdSemUTshpLnKCBZXzJ82bXBgXNnfdmc3gtS24ZmM3ZfK/rYztEDkiTk -s2R1gwDwf5RtDpaf5LD2ufESdbLuT+8blAlscbgYLBcwDquZAY0EWMu6rgEMAKcz -vM1IhpUwBpxPCNdrlMZh7XeLqKUd7hUvQ1KHOuDONxCDnfXdxGCKKI0Ds5I7Kkyp -Wzvcl7PplRy2fYZWwcGtL+Kj01y4L2lXB/xrrVaVwRr4S0FrcbseUGYRafBpR0C1 -Yo24CL1ef4ivsfbER2SyaZ3lrT9Ccv6xfvTluhU8X+2li1ssak/Frvy02u3EORLD -LxaaLQgANgsjnIjv/JQZ4l3xFIJT98tEoL18btg5lGrS2w4yFU1aa1SNsbp7vcu7 -wsqcJmCzX98LyG8/IBGJ5JXmZ03yzWhZ3uhhy1+Avi4GV4Mi0ADwaGMp6O63Mc3w -SL8A/DoCKJLISOc+D5xNfw6C8sYlaOSzQfqY9l4HW/+QbJmEFL2+bnjSHb8yaVU3 -ae2IIrlNkZ5Jamp12Kq6x9Vei0xGk3gd4sqhmHhECdxoJtkX9L5gt436QxdjiTcW -q3V+NNfq94UJu2Ej2kN0fNT0t9RU2n0P/mS0L+1gw5Ex6BX7BIzGL0bZhYomQwAR -AQABiQHOBB8BCAA4FiEEW4DFdUKY8MtV2O1qvO9+KUsJLigFAljLwN0XDIABlKXJ -oDwv5co7CV2OH99yPPRitrECBwAACgkQvO9+KUsJLig2Cgv/T4rXEjHwlbsuTkzp -tgK80Dh92URzBAhPhSJ0kUz2b6y7FgVYgZ95u8elGUS4lOB0GOQSK3y4sCgldTQF -GQpMuvNMX6oNQTv1Z/H9H7Sc6AntozKRA6LQC+7DMxjPh2DEhVLYNqi7gMXtuH8o -Xz5+quarw/xbVmuS4UNqcxakd4A/HW6PayRhuju4+oV2+UmGU0etzGVwKSN/UicC -3Re3mUy8SwJFQ9/3EAfiY0SGzSWH1z7bTRg9Ga2ctYDNzUpyQsgLxD6ZRHcONkOo -GUMEQ96BeSsjT4yW9ED70CcCbhg+pMxR+lnpk4BZ4WML/plBjEb8B1YaRvhYWKd3 -OSVB/JsS6J6Q/y9TTsAJDBLAfw9h7RQKibViuVFSNftAuSdktah5mDwFnL0ZMzVS -3tDVDa5PDqbHEhK55/5EWBg4eNbAukVZmmoLzzERGXuj+LOIRElG3/n3chy1uM73 -B6da3al4gDDNHifPsuozpkVN1EAROZx1K9hGGDZC3yFQTjsJtCRBbmRyZSBIZWlu -ZWNrZSAoUmVsZWFzZSBTaWduaW5nIEtleSmJAdQEEwEIAD4WIQRbgMV1Qpjwy1XY -7Wq8734pSwkuKAUCWMu6rgIbAwUJEswDAAULCQgHAgYVCAkKCwIEFgIDAQIeAQIX -gAAKCRC8734pSwkuKEL9DACEIL5IS9wUty62Bnwd9wK2hmwihXNkTLsOOoi8aCdO -ywPwcIucgAcIO+c/t0lbe4y4sJ1KrKbdyOUQiJAyxobLCSV/MkhIDAmsZB1ZIpF3 -nfmNekRdCVcMpqX8jAwoBS3Q9m2UJz1LeDCLFCvLF0nbyUnqHZP19UOvxmzAyZMA -Ub3W5y1+GMo4yA+3xSFI8ZbjzhawixCCRs69/4p+zCXR4e7LBf6koAHllD/0ZULp -SDjF+t2IkvRrMlM+e+Mxjklinr8v1FRGzmE/kCcdHaP88+iwC2wUKOZtFs4yIBLO -SWdQk9tLPmR8uWgNZmatRJyNvOaxd6EbK3jfckbJGFkmXjH+M9vMqFpoAewZ359F -qjq+Us7AXLAMNUynom7IrtR5Rvsjx6RNtKQYUD6XY5rc7r9js9iGruHDAAW5lyRg -j3wikc0IbV9L1bTsXIp29BsrU9sXUkVEp+xQJZgwqoOduoSjmOK88QdkibDqJiGF -dzIRiXx+Nxv1Pr9L7A4/tq+YMwRfQ+WJFgkrBgEEAdpHDwEBB0DPvkeV6RzXomGF -8jQwp0RXEt2TGFwwI7RkbpYwECY2l7QfV2VybmVyIEtvY2ggKGRpc3Qgc2lnbmlu -ZyAyMDIwKYiaBBMWCgBCFiEEbapuZKdtKEBXG0kCUoiXuCZAOtoFAl9D7DUCGwMF -CRKFxxEFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4HAheAAAoJEFKIl7gmQDraea4A -/24v8c50HSC/Basf4WlREkuzhudplo8iT0BGtTQRdGAmAP9gIZ8dBekg9PRlpe7A -l7ErThn6owVH9szWrUt6jkKOBg== -=h7e4 +mQGNBFjLuq4BDACnM7zNSIaVMAacTwjXa5TGYe13i6ilHe4VL0NShzrgzjcQg531 +3cRgiiiNA7OSOypMqVs73Jez6ZUctn2GVsHBrS/io9NcuC9pVwf8a61WlcEa+EtB +a3G7HlBmEWnwaUdAtWKNuAi9Xn+Ir7H2xEdksmmd5a0/QnL+sX705boVPF/tpYtb +LGpPxa78tNrtxDkSwy8Wmi0IADYLI5yI7/yUGeJd8RSCU/fLRKC9fG7YOZRq0tsO +MhVNWmtUjbG6e73Lu8LKnCZgs1/fC8hvPyARieSV5mdN8s1oWd7oYctfgL4uBleD +ItAA8GhjKejutzHN8Ei/APw6AiiSyEjnPg+cTX8OgvLGJWjks0H6mPZeB1v/kGyZ +hBS9vm540h2/MmlVN2ntiCK5TZGeSWpqddiqusfVXotMRpN4HeLKoZh4RAncaCbZ +F/S+YLeN+kMXY4k3Fqt1fjTX6veFCbthI9pDdHzU9LfUVNp9D/5ktC/tYMORMegV ++wSMxi9G2YWKJkMAEQEAAYkBzgQfAQgAOBYhBFuAxXVCmPDLVdjtarzvfilLCS4o +BQJYy8DdFwyAAZSlyaA8L+XKOwldjh/fcjz0YraxAgcAAAoJELzvfilLCS4oNgoL +/0+K1xIx8JW7Lk5M6bYCvNA4fdlEcwQIT4UidJFM9m+suxYFWIGfebvHpRlEuJTg +dBjkEit8uLAoJXU0BRkKTLrzTF+qDUE79Wfx/R+0nOgJ7aMykQOi0AvuwzMYz4dg +xIVS2Daou4DF7bh/KF8+fqrmq8P8W1ZrkuFDanMWpHeAPx1uj2skYbo7uPqFdvlJ +hlNHrcxlcCkjf1InAt0Xt5lMvEsCRUPf9xAH4mNEhs0lh9c+200YPRmtnLWAzc1K +ckLIC8Q+mUR3DjZDqBlDBEPegXkrI0+MlvRA+9AnAm4YPqTMUfpZ6ZOAWeFjC/6Z +QYxG/AdWGkb4WFindzklQfybEuiekP8vU07ACQwSwH8PYe0UCom1YrlRUjX7QLkn +ZLWoeZg8BZy9GTM1Ut7Q1Q2uTw6mxxISuef+RFgYOHjWwLpFWZpqC88xERl7o/iz +iERJRt/593IctbjO9wenWt2peIAwzR4nz7LqM6ZFTdRAETmcdSvYRhg2Qt8hUE47 +CbQkQW5kcmUgSGVpbmVja2UgKFJlbGVhc2UgU2lnbmluZyBLZXkpiQHUBBMBCAA+ +FiEEW4DFdUKY8MtV2O1qvO9+KUsJLigFAljLuq4CGwMFCRLMAwAFCwkIBwIGFQgJ +CgsCBBYCAwECHgECF4AACgkQvO9+KUsJLihC/QwAhCC+SEvcFLcutgZ8HfcCtoZs +IoVzZEy7DjqIvGgnTssD8HCLnIAHCDvnP7dJW3uMuLCdSqym3cjlEIiQMsaGywkl +fzJISAwJrGQdWSKRd535jXpEXQlXDKal/IwMKAUt0PZtlCc9S3gwixQryxdJ28lJ +6h2T9fVDr8ZswMmTAFG91uctfhjKOMgPt8UhSPGW484WsIsQgkbOvf+Kfswl0eHu +ywX+pKAB5ZQ/9GVC6Ug4xfrdiJL0azJTPnvjMY5JYp6/L9RURs5hP5AnHR2j/PPo +sAtsFCjmbRbOMiASzklnUJPbSz5kfLloDWZmrUScjbzmsXehGyt433JGyRhZJl4x +/jPbzKhaaAHsGd+fRao6vlLOwFywDDVMp6JuyK7UeUb7I8ekTbSkGFA+l2Oa3O6/ +Y7PYhq7hwwAFuZckYI98IpHNCG1fS9W07FyKdvQbK1PbF1JFRKfsUCWYMKqDnbqE +o5jivPEHZImw6iYhhXcyEYl8fjcb9T6/S+wOP7aviQGzBBABCAAdFiEElKXJoDwv +5co7CV2OH99yPPRitrEFAljLv5sACgkQH99yPPRitrFw4gv/XFMFN+/LHsn9hJOP +4rCwl1yUuxXuYmZgc0sRoY3EpeQkJVyKurQuqqKoy2VuoMiF0O1kAQmGoFtVPUk7 +b8hCoutqB5GyeyKcoLP+WINgVhB2gXg7TSp3MPLBKkgqvSDvPitgRxBqFb4LW8LJ +bDbfwGrzIvXfDV3WvsrHVPbc2fhlWdL8d+3AE6mFiXF3eTpgmV3ApSBQV12MkkCk +icLIPmp+ZxZON+OP52ZXkRtfMgOy4Oa/41agrViDAZdMOGeGkhPertQheQZgXzmo +GF5Wz498HPM80Kv35X91l3iGzL+icEtO+tWea2YscsZ6qpRe2lfVPHk3B+anlmCj +m4kM4cBd39xa4HHSVh/bRHbZNtgVr7slQCKxlHgQOGVI5vCxPCwEsgJ2KBk03Nk/ +IA9EKO+czfh3/bHW6uMbEqrYDCnt+hmzZrpKDSGcwS/KOhvMUIMlb7/8vDKum6mp +/8xAtVZ6IAxYZNt3qg7Y7aLRtzCTyqm8rJQrZPtRaQcgLoEimDMEX0PliRYJKwYB +BAHaRw8BAQdAz75Hlekc16JhhfI0MKdEVxLdkxhcMCO0ZG6WMBAmNpe0H1dlcm5l +ciBLb2NoIChkaXN0IHNpZ25pbmcgMjAyMCmImgQTFgoAQhYhBG2qbmSnbShAVxtJ +AlKIl7gmQDraBQJfQ+w1AhsDBQkShccRBQsJCAcCAyICAQYVCgkICwIEFgIDAQIe +BwIXgAAKCRBSiJe4JkA62nmuAP9uL/HOdB0gvwWrH+FpURJLs4bnaZaPIk9ARrU0 +EXRgJgD/YCGfHQXpIPT0ZaXuwJexK04Z+qMFR/bM1q1Leo5CjgaIbQQQEQsAHRYh +BIBhWHD1utaQMzaG0PKthaweQrNnBQJfQ/HmAAoJEPKthaweQrNnIZkA3jG6LcZv +V/URn8Y8OJqsyYa4C3NI4nN+OhEvYhgA4PHzMnALeXIpA2gblvjFIPJPAhDBAU37 +c5PA6+6IdQQQFggAHRYhBK6oTtzwGthsRwHIXGMROuhmWH0KBQJfQ/IlAAoJEGMR +OuhmWH0K1+MA/0uJ5AHcnSfIBEWHNJwwVVLGyrxAWtS2U+zeymp/UvlPAQDErCLZ +l0dBiPG3vlowFx5TNep7tanBs6ZJn8F1ao1tAIkBMwQQAQgAHRYhBNhpISPEBl3q +Xg86tSSbOdJPJeO2BQJfQ/OuAAoJECSbOdJPJeO2DVoH/0o9if66ph6FJrgr+A/W +HNVeHxmM5tUQhpL1wpRS70SKcsJgolf5CxO5iTQf3HlZe544xGbIU/aCTJsWw9zi +UE8KmhAtKV4eL/7oQ7xx4nxPnABLpudtM8A44nsM1x/XiYrJnnDm29QjYEGd2Hi8 +7npc7VWKzLoj+I/WcXquynJi5O9TUxW9Bknd1pjpxFkf8v+msjBzCD5VKJgr0CR8 +wA6peQBWeGZX2HacosMIZH4TfL0r0TFla6LJIkNBz9DyIm1yL4L8oRH0950hQljP +C7TM3L7aRpX+4Kph6llFz6g7MALGFP95kyJ6o+XED9ORuuQVZMBMIkNC0tXOu10V +bdqIdQQQFgoAHRYhBMHTS2khnkruwLocIeP9/yGORbcrBQJfQ/P8AAoJEOP9/yGO +Rbcr3lQBAMas8Vl3Hdl3g2I283lz1uHiGvlwcnk2TLeB+U4zIwC9AQCy0nnazVNt +VQPID1ZCMoaOX7AzOjaqQDLf4j+dVTxgBJgzBGCkgocWCSsGAQQB2kcPAQEHQJmd +fwp8jEN5P3eEjhQiWk6zQi8utvgOvYD57XmE+H8+tCBOaWliZSBZdXRha2EgKEdu +dVBHIFJlbGVhc2UgS2V5KYiaBBMWCgBCFiEErI4RW/c+LY1H+pkI6Y6bLRnGyL0F +AmCkgocCGwMFCQsNBpkFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4HAheAAAoJEOmO +my0Zxsi9/4IA/1rvSr3MU+Sv4jhNDzD+CeC3gmHkPew6pi9VHEsEwdgmAQD2BtiX +7w1sJL/CBylGWv5jxj4345mP9YfZm0RsgzPjDIh1BBAWCAAdFiEEJJyzdxdQdF1c +3TI84mewUjZPAo0FAmFAQ54ACgkQ4mewUjZPAo1CiAD+KTT1UVdQTGHMyvHwZocS +QjU8xhcZrTet+dvvjrE5+4MA/RBdJPZgFevUKu68NEy0Lo+RbkeCtmQJ/c8v5ieF +vW0AiQEzBBABCAAdFiEEEkEkvTtIYq96CkLxALRevUynur4FAmFAQ7cACgkQALRe +vUynur4kaAgAolPR8TNWVS0vXMKrr0k0l2M/8QkZTaLZx1GT9Nx1yb4WJKY7ElPM +YkhGDxetvFBETx0pH/6R3jtj6Crmur+NKHVSRY+rCYpFPDn6ciIOryssRx2G4kCZ +t+nFB9JyDbBOZAR8DK4pN1mAxG/yLDt4oKcUQsP2xlEFum+phxyR8KyYCpkwKRxY +eK+6lfilQuveoUwp/Xx5wXPNUy6q4eOOovCW7gS7I7288NGHCa2ul8sD6vA9C4mM +4Zxaole9P9wwJe1zZFtCIy88zHM9vqv+YM9DxMCaW24+rUztr7eD4bCRdG+QlSh+ +7R/TaqSxY1eAAd1J5tma9CNJO73pTKU+/JhTBGFpSqMTCSskAwMCCAEBBwIDBF6X +D9NmUQDgiyYNbhs1DMJ14mIw812wY1HVx/4QWYWiBunhrvSFxVbzsjD7/Wv+v3bm +MPrL+M2DLyFiSewNmcS0JEdudVBHLmNvbSAoUmVsZWFzZSBTaWduaW5nIEtleSAy +MDIxKYiaBBMTCABCFiEEAvON/3Mf+XywOaHaVJ5pXpBboggFAmFpSqMCGwMFCQ9x +14oFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4HAheAAAoJEFSeaV6QW6IITkoA/RYa +jaTl1eEBU/Gdm12o3jrI55N5xZK2XTqSx25clVyjAP0XwMW/Og5+ND1ri3bAqADV +WlBDUswz8wYxsb0C4kYBkoh1BBAWCgAdFiEEbapuZKdtKEBXG0kCUoiXuCZAOtoF +AmFpTvEACgkQUoiXuCZAOtrJQAEAh7YyykjAy/Qs1yC3ji8iBfIVnPXvblrIx3SR +RyDwRC8BAKtZbEuKTtPlgkLUgMleTcZJ/vEhJE+GvfQ9o5gWCqEFiHUEEBYKAB0W +IQTB00tpIZ5K7sC6HCHj/f8hjkW3KwUCYWlPWgAKCRDj/f8hjkW3Kx4eAQDp6aGS +N/fU4xLl8RSvQUVjVA+aCTrMQR3hRwqw8liF2wEA3O3ECxz6e1+DoItYoJBBLKLw +eiInsGZ/+h5XYrpXTgA= +=4+Sn -----END PGP PUBLIC KEY BLOCK----- diff --git a/libgcrypt.spec b/libgcrypt.spec index 3249111..0c8268e 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -17,12 +17,11 @@ %define build_hmac256 1 -%define separate_hmac256_binary 0 %define libsover 20 %define libsoname %{name}%{libsover} -%define cavs_dir %{_libexecdir}/%{name}/cavs +%define hmac_key orboDeJITITejsirpADONivirpUkvarP Name: libgcrypt -Version: 1.9.4 +Version: 1.10.1 Release: 0 Summary: The GNU Crypto Library License: GPL-2.0-or-later AND LGPL-2.1-or-later AND GPL-3.0-or-later @@ -32,89 +31,26 @@ Source: https://gnupg.org/ftp/gcrypt/libgcrypt/%{name}-%{version}.tar.bz Source1: https://gnupg.org/ftp/gcrypt/libgcrypt/%{name}-%{version}.tar.bz2.sig Source2: baselibs.conf Source3: random.conf -# https://www.gnupg.org/signature_key.en.html -Source4: libgcrypt.keyring -# cavs test framework -Source5: cavs-test.sh -Source6: cavs_driver.pl +Source4: hwf.deny +# https://gnupg.org/signature_key.asc +Source5: libgcrypt.keyring Source99: libgcrypt.changes -Patch1: libgcrypt-1.4.1-rijndael_no_strict_aliasing.patch -Patch3: libgcrypt-1.5.0-LIBGCRYPT_FORCE_FIPS_MODE-env.diff -Patch4: libgcrypt-1.6.1-use-fipscheck.patch -Patch5: libgcrypt-1.6.1-fips-cavs.patch -Patch6: libgcrypt-fix-rng.patch -#PATCH-FIX-SUSE add FIPS CAVS test app for DRBG -Patch7: drbg_test.patch -#PATCH-FIX-UPSTREAM bsc#1064455 fipsdrv patch to enable --algo for dsa-sign -Patch8: libgcrypt-fipsdrv-enable-algo-for-dsa-sign.patch -#PATCH-FIX-UPSTREAM bsc#1064455 fipsdrv patch to enable --algo for dsa-verify -Patch9: libgcrypt-fipsdrv-enable-algo-for-dsa-verify.patch -Patch10: libgcrypt-1.8.3-fips-ctor.patch -Patch11: libgcrypt-1.8.4-use_xfree.patch -Patch12: libgcrypt-1.8.4-allow_FSM_same_state.patch -Patch13: libgcrypt-1.8.4-getrandom.patch -Patch14: libgcrypt-1.8.4-fips_ctor_skip_integrity_check.patch -#PATCH-FIX-SUSE Fix test in FIPS mode -Patch15: libgcrypt-dsa-rfc6979-test-fix.patch -Patch16: libgcrypt-fix-tests-fipsmode.patch -#PATCH-FIX-SUSE bsc#1155337 FIPS: RSA/DSA/ECDSA are missing hashing operation -Patch17: libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch -#PATCH-FIX-SUSE bsc#1161220 FIPS: libgcrypt RSA siggen/keygen: 4k not supported -Patch18: libgcrypt-1.8.4-fips-keygen.patch -#PATCH-FIX-SUSE bsc#1164950 Run self-tests from the constructor -Patch19: libgcrypt-invoke-global_init-from-constructor.patch -#PATCH-FIX-SUSE bsc#1164950 Restore the self-tests from the constructor -Patch20: libgcrypt-Restore-self-tests-from-constructor.patch -Patch21: libgcrypt-FIPS-GMAC_AES-benckmark.patch -Patch22: libgcrypt-global_init-constructor.patch -Patch23: libgcrypt-random_selftests-testentropy.patch -Patch24: libgcrypt-rsa-no-blinding.patch -Patch25: libgcrypt-ecc-ecdsa-no-blinding.patch -#PATCH-FIX-SUSE bsc#1165539 FIPS: Use the new signature operation in PCT -Patch26: libgcrypt-PCT-RSA.patch -Patch27: libgcrypt-PCT-DSA.patch -Patch28: libgcrypt-PCT-ECC.patch -Patch29: libgcrypt-fips_selftest_trigger_file.patch -#PATCH-FIX-SUSE bsc#1189745 The t-lock test is not build with phtread in gcc7, works in gcc11 -Patch30: libgcrypt-pthread-in-t-lock-test.patch -#PATCH-FIX-UPSTREAM bsc#1187110 FIPS: Enable hardware support also in FIPS mode -Patch31: libgcrypt-FIPS-hw-optimizations.patch -#PATCH-FIX-UPSTREAM bsc#1190706 FIPS: Provide module name/identifier and version -Patch32: libgcrypt-FIPS-module-version.patch -#PATCH-FIX-SUSE bsc#1185138 FIPS: Disable 3DES/Triple-DES in FIPS mode -Patch33: libgcrypt-FIPS-disable-3DES.patch -#PATCH-FIX-UPSTREAM bsc#1192131 FIPS: Fix regression tests in FIPS mode -Patch34: libgcrypt-FIPS-fix-regression-tests.patch -#PATCH-FIX-UPSTREAM bsc#1192240 FIPS: RSA KeyGen/SigGen fail with 4096 bit key sizes -Patch35: libgcrypt-FIPS-RSA-keylen.patch -Patch36: libgcrypt-FIPS-RSA-keylen-tests.patch -#PATCH-FIX-UPSTREAM bsc#1193480 FIPS: gcry_mpi_sub_ui: fix subtracting from negative value -Patch37: libgcrypt-FIPS-fix-gcry_mpi_sub_ui.patch -#PATCH-FIX-UPSTREAM bsc#1190700 FIPS: Provide a service-level indicator -Patch38: libgcrypt-FIPS-verify-unsupported-KDF-test.patch -Patch39: libgcrypt-FIPS-HMAC-short-keylen.patch -Patch40: libgcrypt-FIPS-service-indicators.patch -#PATCH-FIX-UPSTREAM bsc#1195385 FIPS: Disable DSA in FIPS mode -Patch41: libgcrypt-FIPS-disable-DSA.patch +Patch1: libgcrypt-1.10.0-allow_FSM_same_state.patch #PATCH-FIX-UPSTREAM bsc#1190700 FIPS: Provide a service-level indicator for PK -Patch42: libgcrypt-FIPS-SLI-pk.patch +Patch2: libgcrypt-FIPS-SLI-pk.patch #PATCH-FIX-SUSE bsc#1190700 FIPS add indicators -Patch43: libgcrypt_indicators_changes.patch -#PATCH-FIX-SUSE bsc#1190700 FIPS allow shake -Patch44: libgcrypt-indicate-shake.patch -#PATCH-FIX-UPSTREAM bsc#1202117 jsc#SLE-24941 FIPS: Port libgcrypt to use jitterentropy -Patch45: libgcrypt-jitterentropy-3.3.0.patch -Patch46: libgcrypt-jitterentropy-3.4.0.patch -#PATCH-FIX-SUSE bsc#1182983 gpg: out of core handler ignored in FIPS mode while typing Tab key to Auto-Completion -Patch47: libgcrypt-out-of-core-handler.patch -#PATCH-FIX-SUSE bsc#1191020 FIPS: Zeroize buffer and digest in check_binary_integrity() -Patch48: libgcrypt-FIPS-Zeroize-hmac.patch +Patch3: libgcrypt-FIPS-SLI-hash-mac.patch #PATCH-FIX-SUSE bsc#1190700 FIPS: Check keylength in gcry_fips_indicator_kdf() -Patch49: libgcrypt-FIPS-kdf-leylength.patch +Patch4: libgcrypt-FIPS-SLI-kdf-leylength.patch +#PATCH-FIX-SUSE bsc#1182983 gpg: out of core handler ignored in FIPS mode while typing Tab key to Auto-Completion +Patch5: libgcrypt-1.10.0-out-of-core-handler.patch +#PATCH-FIX-UPSTREAM bsc#1202117 jsc#SLE-24941 FIPS: Port libgcrypt to use jitterentropy +Patch6: libgcrypt-jitterentropy-3.4.0.patch #PATCH-FIX-SUSE bsc#1202117 FIPS: Get most of the entropy from rndjent_poll -Patch50: libgcrypt-FIPS-rndjent_poll.patch +Patch7: libgcrypt-FIPS-rndjent_poll.patch +#PATCH-FIX-SUSE Check the FIPS "module is complete" trigger file .fips +Patch8: libgcrypt-1.10.0-use-fipscheck.patch BuildRequires: automake >= 1.14 -BuildRequires: fipscheck BuildRequires: libgpg-error-devel >= 1.27 BuildRequires: libtool BuildRequires: makeinfo @@ -164,133 +100,92 @@ understanding of applied cryptography is required to use Libgcrypt. This package contains needed files to compile and link against the library. -%package cavs -Summary: The GNU Crypto Library -License: GFDL-1.1-only AND GPL-2.0-or-later AND LGPL-2.1-or-later AND MIT -Group: Development/Libraries/C and C++ -Requires: %{libsoname} = %{version} -Requires: %{libsoname}-hmac - -%description cavs -CAVS testing framework for libgcrypt - -%if 0%{?separate_hmac256_binary} -%package hmac256 -Summary: The GNU Crypto Library -License: GPL-2.0-or-later AND LGPL-2.1-or-later -Group: Development/Libraries/C and C++ -Requires: %{libsoname} = %{version} -Requires: libgpg-error-devel >= 1.27 - -%description hmac256 -Libgcrypt is a general purpose library of cryptographic building -blocks. It is originally based on code used by GnuPG. It does not -provide any implementation of OpenPGP or other protocols. Thorough -understanding of applied cryptography is required to use Libgcrypt. -%endif - %prep -%setup -q -%autopatch -p1 +%autosetup -p1 + +# Rename the internal .hmac file to include the so library version +sed -i "s/libgcrypt\.so\.hmac/\.libgcrypt\.so\.%{libsover}\.hmac/g" src/Makefile.am src/Makefile.in %build echo building with build_hmac256 set to %{build_hmac256} + +export PUBKEYS="dsa elgamal rsa ecc" +export CIPHERS="arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea salsa20 gost28147 chacha20 sm4" +export DIGESTS="crc gostr3411-94 md4 md5 rmd160 sha1 sha256 sha512 sha3 tiger whirlpool stribog blake2 sm3" +export KDFS="s2k pkdf2 scrypt" + autoreconf -fi date=$(date -u '+%%Y-%%m-%%dT%%H:%%M+0000' -r %{SOURCE99}) sed -e "s,BUILD_TIMESTAMP=.*,BUILD_TIMESTAMP=$date," -i configure export CFLAGS="%{optflags} $(getconf LFS_CFLAGS)" %configure \ - --with-fips-module-version="Libgcrypt version %{version}-$SOURCE_DATE_EPOCH" \ + --with-fips-module-version="Libgcrypt version %{version}-%{release}" \ + --enable-hmac-binary-check="%{hmac_key}" \ + --enable-ciphers="$CIPHERS" \ + --enable-pubkey-ciphers="$PUBKEYS" \ + --enable-digests="$DIGESTS" \ + --enable-kdfs="$KDFS" \ --enable-noexecstack \ --disable-static \ --enable-m-guard \ %ifarch %{sparc} --disable-asm \ %endif - --enable-hmac-binary-check \ - --enable-random=linux + --enable-random=getentropy \ + %{nil} %make_build -%if 0%{?build_hmac256} -# this is a hack that re-defines the __os_install_post macro -# for a simple reason: the macro strips the binaries and thereby -# invalidates a HMAC that may have been created earlier. -# solution: create the hashes _after_ the macro runs. -# -# this shows up earlier because otherwise the %%expand of -# the macro is too late. -%{expand:%%global __os_install_post {%__os_install_post - fipshmac %{buildroot}/%{_bindir}/hmac256 - fipshmac %{buildroot}/%{_libdir}/*.so.?? -}} -%endif - %check -fipshmac src/.libs/libgcrypt.so.?? %make_build check - # run the regression tests also in FIPS mode LIBGCRYPT_FORCE_FIPS_MODE=1 make -k check VERBOSE=1 || true +# Install the FIPS hmac file +cp src/.libgcrypt.so.%{libsover}.hmac %{buildroot}%{_libdir}/ + +# create the FIPS "module is complete" trigger file +%if 0%{?build_hmac256} +touch %{buildroot}%{_libdir}/.%{name}.so.%{libsover}.fips +%endif + %install %make_install rm %{buildroot}%{_libdir}/%{name}.la -# cavs -install -m 0755 -d %{buildroot}%{cavs_dir} -install -m 0755 %{SOURCE5} %{buildroot}%{cavs_dir} -install -m 0755 %{SOURCE6} %{buildroot}%{cavs_dir} - -mv %{buildroot}%{_bindir}/fipsdrv %{buildroot}%{cavs_dir} -mv %{buildroot}%{_bindir}/drbg_test %{buildroot}%{cavs_dir} - -# create the FIPS "module is complete" trigger file -%if 0%{?build_hmac256} -touch %{buildroot}/%{_libdir}/.%{name}.so.%{libsover}.fips -%endif - # Create /etc/gcrypt directory and install random.conf mkdir -p -m 0755 %{buildroot}%{_sysconfdir}/gcrypt install -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/gcrypt/random.conf +install -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/gcrypt/hwf.deny %post -n %{libsoname} -p /sbin/ldconfig %postun -n %{libsoname} -p /sbin/ldconfig %files -n %{libsoname} -%license COPYING.LIB +%license COPYING COPYING.LIB LICENSES +%doc AUTHORS ChangeLog NEWS README THANKS TODO %{_libdir}/%{name}.so.* %dir %{_sysconfdir}/gcrypt %config(noreplace) %{_sysconfdir}/gcrypt/random.conf -%if 0%{?build_hmac256} -%{_libdir}/.libgcrypt.so.*.hmac -%endif +%config(noreplace) %{_sysconfdir}/gcrypt/hwf.deny %files -n %{libsoname}-hmac +%{_libdir}/.libgcrypt.so.*.hmac %if 0%{?build_hmac256} %{_libdir}/.libgcrypt.so.*.fips %endif %files devel -%license COPYING COPYING.LIB -%doc AUTHORS ChangeLog NEWS README THANKS TODO -%{_infodir}/gcrypt.info*%{ext_info} +%license COPYING COPYING.LIB LICENSES %{_bindir}/dumpsexp +%{_bindir}/hmac256 %{_bindir}/mpicalc %{_bindir}/%{name}-config %{_libdir}/%{name}.so -%{_includedir}/gcrypt*.h -%{_datadir}/aclocal/%{name}.m4 %{_libdir}/pkgconfig/libgcrypt.pc - -%if 0%{?separate_hmac256_binary} -%files hmac256 -%endif -%{_bindir}/hmac256 -%{_bindir}/.hmac256.hmac -%doc %{_mandir}/man1/hmac256.1* - -%files cavs -%{_libexecdir}/%{name} +%{_datadir}/aclocal/%{name}.m4 +%{_includedir}/gcrypt*.h +%{_infodir}/gcrypt.info*%{ext_info}* +%{_mandir}/man1/* %changelog From f23b31a15219caf35f06ac3a558a78d882247b21a8265304657a086cb34ee71c Mon Sep 17 00:00:00 2001 From: Pedro Monreal Gonzalez Date: Fri, 25 Nov 2022 14:49:39 +0000 Subject: [PATCH 2/2] Accepting request 1038227 from home:pmonrealgonzalez:branches:devel:libraries:c_c++ - libgcrypt-1.4.1-rijndael_no_strict_aliasing.patch OBS-URL: https://build.opensuse.org/request/show/1038227 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libgcrypt?expand=0&rev=161 --- libgcrypt.changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgcrypt.changes b/libgcrypt.changes index db5ad97..4aa94b5 100644 --- a/libgcrypt.changes +++ b/libgcrypt.changes @@ -95,7 +95,7 @@ Wed Sep 14 13:34:13 UTC 2022 - Pedro Monreal is checked. Rename libgcrypt-1.6.1-use-fipscheck.patch to libgcrypt-1.10.0-use-fipscheck.patch * Remove patches fixed upstream: - - libgcrypt-1.10.0-rijndael_no_strict_aliasing.patch + - libgcrypt-1.4.1-rijndael_no_strict_aliasing.patch - libgcrypt-1.5.0-LIBGCRYPT_FORCE_FIPS_MODE-env.diff - libgcrypt-fix-rng.patch - libgcrypt-1.8.3-fips-ctor.patch