Allow SHA256 and SHA384 data hash for BLISS signatures.
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 25 Feb 2015 20:12:30 +0000 (21:12 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 26 Feb 2015 07:56:12 +0000 (08:56 +0100)
The default is SHA512 since this hash function is also
used for the c_indices random oracle.

17 files changed:
NEWS
src/libstrongswan/asn1/oid.txt
src/libstrongswan/credentials/keys/public_key.c
src/libstrongswan/credentials/keys/public_key.h
src/libstrongswan/crypto/hashers/hasher.c
src/libstrongswan/plugins/bliss/bliss_plugin.c
src/libstrongswan/plugins/bliss/bliss_private_key.c
src/libstrongswan/plugins/bliss/bliss_public_key.c
src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c
src/libstrongswan/tests/suites/test_hasher.c
src/pki/commands/acert.c
src/pki/commands/gen.c
src/pki/commands/issue.c
src/pki/commands/pub.c
src/pki/commands/req.c
src/pki/commands/self.c
src/pki/commands/signcrl.c

diff --git a/NEWS b/NEWS
index e43159f..eb9cba5 100644 (file)
--- a/NEWS
+++ b/NEWS
   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
 ----------------
index bf392da..5e49074 100644 (file)
                     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           ""
index 40d9610..c342ac1 100644 (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;
        }
index ef681c9..9cdcc8e 100644 (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,
 };
index b5e1134..a569303 100644 (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:
index 2021885..07597c3 100644 (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),
        };
index 0f89bed..74c6cfe 100644 (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);
index 4564d7c..0175b0f 100644 (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);
index 0414798..8b4e9cb 100644 (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);
                }
index 41a9d64..14cc321 100644 (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 }
 };
 
index 03d90a1..e571318 100644 (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)
index c39644e..8b11854 100644 (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
index c1d4cf8..fba0238 100644 (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)
        {
index 843b784..ccc3c42 100644 (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
index fbe47ec..39d7162 100644 (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)
        {
index a67115d..8dcb046 100644 (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)
        {
index 212e1a8..4b81c77 100644 (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)