Allow SHA256 and SHA384 data hash for BLISS signatures.

The default is SHA512 since this hash function is also
used for the c_indices random oracle.
This commit is contained in:
Andreas Steffen 2015-02-25 21:12:30 +01:00
parent a7f0ab786d
commit 27bd0fed93
17 changed files with 133 additions and 42 deletions

4
NEWS
View File

@ -19,6 +19,10 @@
Windows 7 IKEv2 clients, which announces its services over the tunnel if the
negotiated IPsec policy allows it.
- Upgrade of the BLISS post-quantum signature algorithm to the improved BLISS-B
variant. Can be used in conjunction with the SHA256, SHA384 and SHA512 hash
algorithms with SHA512 being the default.
strongswan-5.2.2
----------------

View File

@ -224,6 +224,8 @@
0x08 "BLISS-B_IV" OID_BLISS_B_IV
0x03 "blissSigType"
0x01 "BLISS-with-SHA512" OID_BLISS_WITH_SHA512
0x02 "BLISS-with-SHA384" OID_BLISS_WITH_SHA384
0x03 "BLISS-with-SHA256" OID_BLISS_WITH_SHA256
0x89 ""
0x31 ""
0x01 ""

View File

@ -43,6 +43,8 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_BLISS_WITH_SHA512,
"ECDSA-256",
"ECDSA-384",
"ECDSA-521",
"BLISS_WITH_SHA256",
"BLISS_WITH_SHA384",
"BLISS_WITH_SHA512",
);
@ -136,6 +138,10 @@ signature_scheme_t signature_scheme_from_oid(int oid)
case OID_BLISS_PUBLICKEY:
case OID_BLISS_WITH_SHA512:
return SIGN_BLISS_WITH_SHA512;
case OID_BLISS_WITH_SHA256:
return SIGN_BLISS_WITH_SHA256;
case OID_BLISS_WITH_SHA384:
return SIGN_BLISS_WITH_SHA384;
default:
return SIGN_UNKNOWN;
}

View File

@ -93,6 +93,10 @@ enum signature_scheme_t {
SIGN_ECDSA_384,
/** ECDSA on the P-521 curve with SHA-512 as in RFC 4754 */
SIGN_ECDSA_521,
/** BLISS with SHA-256 */
SIGN_BLISS_WITH_SHA256,
/** BLISS with SHA-384 */
SIGN_BLISS_WITH_SHA384,
/** BLISS with SHA-512 */
SIGN_BLISS_WITH_SHA512,
};

View File

@ -326,6 +326,10 @@ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key)
case KEY_BLISS:
switch (alg)
{
case HASH_SHA256:
return OID_BLISS_WITH_SHA256;
case HASH_SHA384:
return OID_BLISS_WITH_SHA384;
case HASH_SHA512:
return OID_BLISS_WITH_SHA512;
default:

View File

@ -55,9 +55,17 @@ METHOD(plugin_t, get_features, int,
PLUGIN_REGISTER(PUBKEY, bliss_public_key_load, TRUE),
PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
/* signature schemes, private */
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA256),
PLUGIN_DEPENDS(HASHER, HASH_SHA256),
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA384),
PLUGIN_DEPENDS(HASHER, HASH_SHA384),
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA512),
PLUGIN_DEPENDS(HASHER, HASH_SHA512),
/* signature verification schemes */
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA256),
PLUGIN_DEPENDS(HASHER, HASH_SHA256),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA384),
PLUGIN_DEPENDS(HASHER, HASH_SHA384),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA512),
PLUGIN_DEPENDS(HASHER, HASH_SHA512),
};

View File

@ -158,18 +158,20 @@ static void greedy_sc(int8_t *s1, int8_t *s2, int n, uint16_t *c_indices,
}
/**
* Compute a BLISS signature based on a SHA-512 hash
* Compute a BLISS signature
*/
static bool sign_bliss_with_sha512(private_bliss_private_key_t *this,
chunk_t data, chunk_t *signature)
static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
chunk_t data, chunk_t *signature)
{
rng_t *rng;
hash_algorithm_t alg;
hasher_t *hasher;
bliss_fft_t *fft;
bliss_signature_t *sig;
bliss_sampler_t *sampler = NULL;
uint8_t seed_buf[32], data_hash_buf[HASH_SIZE_SHA512];
rng_t *rng;
hasher_t *hasher;
hash_algorithm_t mgf1_alg;
size_t mgf1_seed_len;
uint8_t mgf1_seed_buf[HASH_SIZE_SHA512], data_hash_buf[HASH_SIZE_SHA512];
chunk_t mgf1_seed, data_hash;
uint16_t q, q2, p, p2, *c_indices, tests = 0;
uint32_t *ay;
int32_t *y1, *y2, *z1, *z2, *u, *s1c, *s2c;
@ -177,39 +179,46 @@ static bool sign_bliss_with_sha512(private_bliss_private_key_t *this,
int32_t scalar, norm, ui;
int16_t *ud, *uz2d, *z2d, value;
int i, n;
size_t seed_len;
double mean1 = 0, mean2 = 0, sigma1 = 0, sigma2 = 0;
chunk_t seed;
chunk_t data_hash = { data_hash_buf, sizeof(data_hash_buf) };
bool accepted, positive, success = FALSE, use_bliss_b;
/* Initialize signature */
*signature = chunk_empty;
/* Create data hash */
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
hasher = lib->crypto->create_hasher(lib->crypto, alg);
if (!hasher)
{
return FALSE;
}
data_hash = chunk_create(data_hash_buf, hasher->get_hash_size(hasher));
if (!hasher->get_hash(hasher, data, data_hash_buf))
{
hasher->destroy(hasher);
return FALSE;
}
hasher->destroy(hasher);
/* Create SHA512 hasher for c_indices oracle */
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
if (!hasher)
{
return FALSE;
}
/* Set MGF1 hash algorithm and seed length based on security strength */
if (this->set->strength > 160)
{
alg = HASH_SHA256;
seed_len = HASH_SIZE_SHA256;
mgf1_alg = HASH_SHA256;
mgf1_seed_len = HASH_SIZE_SHA256;
}
else
{
alg = HASH_SHA1;
seed_len = HASH_SIZE_SHA1;
mgf1_alg = HASH_SHA1;
mgf1_seed_len = HASH_SIZE_SHA1;
}
seed = chunk_create(seed_buf, seed_len);
mgf1_seed = chunk_create(mgf1_seed_buf, mgf1_seed_len);
rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
if (!rng)
@ -260,13 +269,13 @@ static bool sign_bliss_with_sha512(private_bliss_private_key_t *this,
{
tests++;
if (!rng->get_bytes(rng, seed_len, seed_buf))
if (!rng->get_bytes(rng, mgf1_seed_len, mgf1_seed_buf))
{
goto end;
}
DESTROY_IF(sampler);
sampler = bliss_sampler_create(alg, seed, this->set);
sampler = bliss_sampler_create(mgf1_alg, mgf1_seed, this->set);
if (!sampler)
{
goto end;
@ -507,8 +516,12 @@ METHOD(private_key_t, sign, bool,
{
switch (scheme)
{
case SIGN_BLISS_WITH_SHA256:
return sign_bliss(this, HASH_SHA256, data, signature);
case SIGN_BLISS_WITH_SHA384:
return sign_bliss(this, HASH_SHA384, data, signature);
case SIGN_BLISS_WITH_SHA512:
return sign_bliss_with_sha512(this, data, signature);
return sign_bliss(this, HASH_SHA512, data, signature);
default:
DBG1(DBG_LIB, "signature scheme %N not supported with BLISS",
signature_scheme_names, scheme);

View File

@ -59,8 +59,8 @@ METHOD(public_key_t, get_type, key_type_t,
/**
* Verify a BLISS signature based on a SHA-512 hash
*/
static bool verify_bliss_with_sha512(private_bliss_public_key_t *this,
chunk_t data, chunk_t signature)
static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
chunk_t data, chunk_t signature)
{
int i, n;
int32_t *z1, *u;
@ -68,23 +68,33 @@ static bool verify_bliss_with_sha512(private_bliss_public_key_t *this,
uint16_t q, q2, p, *c_indices, *indices;
uint32_t *az;
uint8_t data_hash_buf[HASH_SIZE_SHA512];
chunk_t data_hash = { data_hash_buf, sizeof(data_hash_buf) };
chunk_t data_hash;
hasher_t *hasher;
bliss_fft_t *fft;
bliss_signature_t *sig;
bool success = FALSE;
/* Create data hash */
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
hasher = lib->crypto->create_hasher(lib->crypto, alg);
if (!hasher )
{
return FALSE;
}
data_hash = chunk_create(data_hash_buf, hasher->get_hash_size(hasher));
if (!hasher->get_hash(hasher, data, data_hash_buf))
{
hasher->destroy(hasher);
return FALSE;
}
hasher->destroy(hasher);
/* Create SHA512 hasher for c_indices oracle */
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
if (!hasher)
{
return FALSE;
}
sig = bliss_signature_create_from_data(this->set, signature);
if (!sig)
@ -190,8 +200,12 @@ METHOD(public_key_t, verify, bool,
{
switch (scheme)
{
case SIGN_BLISS_WITH_SHA256:
return verify_bliss(this, HASH_SHA256, data, signature);
case SIGN_BLISS_WITH_SHA384:
return verify_bliss(this, HASH_SHA384, data, signature);
case SIGN_BLISS_WITH_SHA512:
return verify_bliss_with_sha512(this, data, signature);
return verify_bliss(this, HASH_SHA512, data, signature);
default:
DBG1(DBG_LIB, "signature scheme %N not supported by BLISS",
signature_scheme_names, scheme);

View File

@ -23,6 +23,7 @@ static u_int key_strength[] = { 128, 160, 192 };
START_TEST(test_bliss_sign_all)
{
signature_scheme_t signature_scheme;
private_key_t *privkey, *privkey1;
public_key_t *pubkey, *pubkey1;
chunk_t msg, signature, privkey_blob, pubkey_blob, pubkey_fp, privkey_fp;
@ -32,6 +33,18 @@ START_TEST(test_bliss_sign_all)
{
int verify_count = 1000;
switch (k)
{
case 1:
signature_scheme = SIGN_BLISS_WITH_SHA256;
break;
case 2:
signature_scheme = SIGN_BLISS_WITH_SHA384;
break;
default:
signature_scheme = SIGN_BLISS_WITH_SHA512;
}
/* enforce BLISS-B key for k = 2, 3 */
lib->settings->set_bool(lib->settings,
"%s.plugins.bliss.use_bliss_b", k >= 2, lib->ns);
@ -105,9 +118,9 @@ START_TEST(test_bliss_sign_all)
/* generate and verify 1000 BLISS signatures */
while (verify_count--)
{
ck_assert(privkey->sign(privkey, SIGN_BLISS_WITH_SHA512, msg,
ck_assert(privkey->sign(privkey, signature_scheme, msg,
&signature));
ck_assert(pubkey->verify(pubkey, SIGN_BLISS_WITH_SHA512, msg,
ck_assert(pubkey->verify(pubkey, signature_scheme, msg,
signature));
free(signature.ptr);
}

View File

@ -48,6 +48,9 @@ static hasher_oid_t oids[] = {
{ OID_ECDSA_WITH_SHA256, HASH_SHA256, KEY_ECDSA },
{ OID_ECDSA_WITH_SHA384, HASH_SHA384, KEY_ECDSA },
{ OID_ECDSA_WITH_SHA512, HASH_SHA512, KEY_ECDSA },
{ OID_BLISS_WITH_SHA256, HASH_SHA256, KEY_BLISS },
{ OID_BLISS_WITH_SHA384, HASH_SHA384, KEY_BLISS },
{ OID_BLISS_WITH_SHA512, HASH_SHA512, KEY_BLISS },
{ OID_UNKNOWN, HASH_UNKNOWN, KEY_ECDSA }
};

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -168,8 +169,11 @@ static int acert()
}
if (private->get_type(private) == KEY_BLISS)
{
/* currently only SHA-512 is supported */
digest = HASH_SHA512;
/* the default hash function is SHA512. SHA1 is not supported */
if (digest == HASH_SHA1)
{
digest = HASH_SHA512;
}
}
if (hex)

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 Martin Willi
* Copyright (C) 2014 Andreas Steffen
* Copyright (C) 2014-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -365,8 +366,11 @@ static int issue()
if (private->get_type(private) == KEY_BLISS)
{
/* currently only SHA-512 is supported */
digest = HASH_SHA512;
/* the default hash function is SHA512. SHA1 is not supported */
if (digest == HASH_SHA1)
{
digest = HASH_SHA512;
}
}
if (hex)
{

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
* Copyright (C) 2009 Andreas Steffen
* Copyright (C) 2009-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* HSR Hochschule fuer Technik Rapperswil
*
@ -104,8 +105,11 @@ static int req()
if (type == KEY_BLISS)
{
/* currently only SHA-512 is supported */
digest = HASH_SHA512;
/* the default hash function is SHA512. SHA1 is not supported */
if (digest == HASH_SHA1)
{
digest = HASH_SHA512;
}
}
if (!dn)
{

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -264,8 +265,11 @@ static int self()
if (type == KEY_BLISS)
{
/* currently only SHA-512 is supported */
digest = HASH_SHA512;
/* the default hash function is SHA512. SHA1 is not supported */
if (digest == HASH_SHA1)
{
digest = HASH_SHA512;
}
}
if (!dn)
{

View File

@ -337,8 +337,11 @@ static int sign_crl()
}
if (private->get_type(private) == KEY_BLISS)
{
/* currently only SHA-512 is supported */
digest = HASH_SHA512;
/* the default hash function is SHA512. SHA1 is not supported */
if (digest == HASH_SHA1)
{
digest = HASH_SHA512;
}
}
if (basecrl)