support of SHA224-based certificate signatures
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 5 Aug 2009 20:01:13 +0000 (22:01 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 5 Aug 2009 20:01:44 +0000 (22:01 +0200)
18 files changed:
src/libstrongswan/credentials/keys/public_key.c
src/libstrongswan/credentials/keys/public_key.h
src/libstrongswan/crypto/hashers/hasher.c
src/libstrongswan/crypto/hashers/hasher.h
src/libstrongswan/plugins/gcrypt/gcrypt_hasher.c
src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
src/libstrongswan/plugins/openssl/openssl_hasher.c
src/libstrongswan/plugins/openssl/openssl_plugin.c
src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
src/libstrongswan/plugins/sha2/sha2_hasher.c
src/libstrongswan/plugins/sha2/sha2_plugin.c
src/libstrongswan/plugins/test_vectors/test_vectors.h
src/libstrongswan/plugins/test_vectors/test_vectors/sha2.c

index 452aa5c..a5f5470 100644 (file)
@@ -28,6 +28,7 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
        "RSA_EMSA_PKCS1_NULL",
        "RSA_EMSA_PKCS1_MD5",
        "RSA_EMSA_PKCS1_SHA1",
+       "RSA_EMSA_PKCS1_SHA224",
        "RSA_EMSA_PKCS1_SHA256",
        "RSA_EMSA_PKCS1_SHA384",
        "RSA_EMSA_PKCS1_SHA512",
@@ -51,6 +52,9 @@ signature_scheme_t signature_scheme_from_oid(int oid)
                case OID_SHA1_WITH_RSA:
                case OID_SHA1:
                        return SIGN_RSA_EMSA_PKCS1_SHA1;
+               case OID_SHA224_WITH_RSA:
+               case OID_SHA224:
+                       return SIGN_RSA_EMSA_PKCS1_SHA224;
                case OID_SHA256_WITH_RSA:
                case OID_SHA256:
                        return SIGN_RSA_EMSA_PKCS1_SHA256;
index c58531b..be5f3bd 100644 (file)
@@ -66,6 +66,8 @@ enum signature_scheme_t {
        SIGN_RSA_EMSA_PKCS1_MD5,
        /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-1     */
        SIGN_RSA_EMSA_PKCS1_SHA1,
+       /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-224   */
+       SIGN_RSA_EMSA_PKCS1_SHA224,
        /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-256   */
        SIGN_RSA_EMSA_PKCS1_SHA256,
        /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-384   */
index c58c2ad..4d6904e 100644 (file)
@@ -26,6 +26,7 @@ ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
        "HASH_MD4",
        "HASH_MD5",
        "HASH_SHA1",
+       "HASH_SHA224",
        "HASH_SHA256",
        "HASH_SHA384",
        "HASH_SHA512"
@@ -47,6 +48,9 @@ hash_algorithm_t hasher_algorithm_from_oid(int oid)
                case OID_SHA1:
                case OID_SHA1_WITH_RSA:
                        return HASH_SHA1;
+               case OID_SHA224:
+               case OID_SHA224_WITH_RSA:
+                       return HASH_SHA224;
                case OID_SHA256:
                case OID_SHA256_WITH_RSA:
                        return HASH_SHA256;
@@ -79,6 +83,9 @@ int hasher_algorithm_to_oid(hash_algorithm_t alg)
                case HASH_SHA1:
                        oid = OID_SHA1;
                        break;
+               case HASH_SHA224:
+                       oid = OID_SHA224;
+                       break;
                case HASH_SHA256:
                        oid = OID_SHA256;
                        break;
@@ -112,6 +119,9 @@ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg)
                case HASH_SHA1:
                        oid = OID_SHA1_WITH_RSA;
                        break;
+               case HASH_SHA224:
+                       oid = OID_SHA224_WITH_RSA;
+                       break;
                case HASH_SHA256:
                        oid = OID_SHA256_WITH_RSA;
                        break;
index 098739f..6deed37 100644 (file)
@@ -40,15 +40,17 @@ enum hash_algorithm_t {
        HASH_MD4                        = 3,
        HASH_MD5                        = 4,
        HASH_SHA1                       = 5,
-       HASH_SHA256             = 6,
-       HASH_SHA384             = 7,
-       HASH_SHA512             = 8
+       HASH_SHA224                     = 6,
+       HASH_SHA256             = 7,
+       HASH_SHA384             = 8,
+       HASH_SHA512             = 9
 };
 
 #define HASH_SIZE_MD2          16
 #define HASH_SIZE_MD4          16
 #define HASH_SIZE_MD5          16
 #define HASH_SIZE_SHA1         20
+#define HASH_SIZE_SHA224       28
 #define HASH_SIZE_SHA256       32
 #define HASH_SIZE_SHA384       48
 #define HASH_SIZE_SHA512       64
index 785ebda..41e17c8 100644 (file)
@@ -116,6 +116,9 @@ gcrypt_hasher_t *gcrypt_hasher_create(hash_algorithm_t algo)
                case HASH_SHA1:
                        gcrypt_alg = GCRY_MD_SHA1;
                        break;
+               case HASH_SHA224:
+                       gcrypt_alg = GCRY_MD_SHA224;
+                       break;
                case HASH_SHA256:
                        gcrypt_alg = GCRY_MD_SHA256;
                        break;
index 547329d..03c9bbb 100644 (file)
@@ -148,6 +148,8 @@ plugin_t *plugin_create()
                                        (hasher_constructor_t)gcrypt_hasher_create);
        lib->crypto->add_hasher(lib->crypto, HASH_MD5,
                                        (hasher_constructor_t)gcrypt_hasher_create);
+       lib->crypto->add_hasher(lib->crypto, HASH_SHA224,
+                                       (hasher_constructor_t)gcrypt_hasher_create);
        lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
                                        (hasher_constructor_t)gcrypt_hasher_create);
        lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
index 0df9fda..e0e8015 100644 (file)
@@ -226,6 +226,8 @@ static bool sign(private_gcrypt_rsa_private_key_t *this, signature_scheme_t sche
                        return sign_raw(this, data, sig);
                case SIGN_RSA_EMSA_PKCS1_SHA1:
                        return sign_pkcs1(this, HASH_SHA1, "sha1", data, sig);
+               case SIGN_RSA_EMSA_PKCS1_SHA224:
+                       return sign_pkcs1(this, HASH_SHA224, "sha224", data, sig);
                case SIGN_RSA_EMSA_PKCS1_SHA256:
                        return sign_pkcs1(this, HASH_SHA256, "sha256", data, sig);
                case SIGN_RSA_EMSA_PKCS1_SHA384:
index f5e749d..4d9c88c 100644 (file)
@@ -188,6 +188,8 @@ static bool verify(private_gcrypt_rsa_public_key_t *this,
                        return verify_pkcs1(this, HASH_MD5, "md5", data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA1:
                        return verify_pkcs1(this, HASH_SHA1, "sha1", data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA224:
+                       return verify_pkcs1(this, HASH_SHA224, "sha224", data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA256:
                        return verify_pkcs1(this, HASH_SHA256, "sha256", data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA384:
index cbc1127..259c8e9 100644 (file)
@@ -301,6 +301,8 @@ static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
                        return build_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA1:
                        return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA224:
+                       return build_emsa_pkcs1_signature(this, HASH_SHA224, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA256:
                        return build_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA384:
index cf55e1f..c26187c 100644 (file)
@@ -301,6 +301,8 @@ static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme
                        return verify_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA1:
                        return verify_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA224:
+                       return verify_emsa_pkcs1_signature(this, HASH_SHA224, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA256:
                        return verify_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA384:
index ed3e579..90a5229 100644 (file)
@@ -65,6 +65,7 @@ static openssl_algorithm_t integrity_algs[] = {
        {HASH_MD2,              "md2"},
        {HASH_MD5,              "md5"},
        {HASH_SHA1,             "sha1"},
+       {HASH_SHA224,   "sha224"},
        {HASH_SHA256,   "sha256"},
        {HASH_SHA384,   "sha384"},
        {HASH_SHA512,   "sha512"},
index a90dff7..c35dbcc 100644 (file)
@@ -238,6 +238,8 @@ plugin_t *plugin_create()
                                        (hasher_constructor_t)openssl_hasher_create);
        lib->crypto->add_hasher(lib->crypto, HASH_MD5,
                                        (hasher_constructor_t)openssl_hasher_create);
+       lib->crypto->add_hasher(lib->crypto, HASH_SHA224,
+                                       (hasher_constructor_t)openssl_hasher_create);
        lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
                                        (hasher_constructor_t)openssl_hasher_create);
        lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
index c5d4142..95c0ffd 100644 (file)
@@ -165,6 +165,8 @@ static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t sch
                        return build_emsa_pkcs1_signature(this, NID_undef, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA1:
                        return build_emsa_pkcs1_signature(this, NID_sha1, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA224:
+                       return build_emsa_pkcs1_signature(this, NID_sha224, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA256:
                        return build_emsa_pkcs1_signature(this, NID_sha256, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA384:
index 89912f2..bc1ba35 100644 (file)
@@ -143,6 +143,8 @@ static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t sc
                        return verify_emsa_pkcs1_signature(this, NID_undef, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA1:
                        return verify_emsa_pkcs1_signature(this, NID_sha1, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA224:
+                       return verify_emsa_pkcs1_signature(this, NID_sha224, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA256:
                        return verify_emsa_pkcs1_signature(this, NID_sha256, data, signature);
                case SIGN_RSA_EMSA_PKCS1_SHA384:
index 0e8811c..645f4d7 100644 (file)
@@ -58,6 +58,11 @@ struct private_sha256_hasher_t {
 };
 
 
+static const u_int32_t sha224_hashInit[8] = {
+       0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511,
+       0x64f98fa7, 0xbefa4fa4 
+};
+
 static const u_int32_t sha256_hashInit[8] = {
        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
        0x1f83d9ab, 0x5be0cd19
@@ -422,6 +427,21 @@ static void sha512_final(private_sha512_hasher_t *ctx)
 }
 
 /**
+ * Implementation of hasher_t.get_hash for SHA224.
+ */
+static void get_hash224(private_sha256_hasher_t *this, 
+                                               chunk_t chunk, u_int8_t *buffer)
+{
+       sha256_write(this, chunk.ptr, chunk.len);
+       if (buffer != NULL)
+       {
+               sha256_final(this);
+               memcpy(buffer, this->sha_out, HASH_SIZE_SHA224);
+               this->public.hasher_interface.reset(&(this->public.hasher_interface));
+       }
+}
+
+/**
  * Implementation of hasher_t.get_hash for SHA256.
  */
 static void get_hash256(private_sha256_hasher_t *this, 
@@ -467,6 +487,25 @@ static void get_hash512(private_sha512_hasher_t *this,
 }
 
 /**
+ * Implementation of hasher_t.allocate_hash for SHA224.
+ */
+static void allocate_hash224(private_sha256_hasher_t *this, 
+                                                        chunk_t chunk, chunk_t *hash)
+{
+       chunk_t allocated_hash;
+       
+       sha256_write(this, chunk.ptr, chunk.len);
+       if (hash != NULL)
+       {
+               sha256_final(this);
+               allocated_hash = chunk_alloc(HASH_SIZE_SHA224);
+               memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA224);
+               this->public.hasher_interface.reset(&(this->public.hasher_interface));
+               *hash = allocated_hash;
+       }
+}
+
+/**
  * Implementation of hasher_t.allocate_hash for SHA256.
  */
 static void allocate_hash256(private_sha256_hasher_t *this, 
@@ -524,6 +563,14 @@ static void allocate_hash512(private_sha512_hasher_t *this,
 }
 
 /**
+ * Implementation of hasher_t.get_hash_size for SHA224.
+ */
+static size_t get_hash_size224(private_sha256_hasher_t *this)
+{
+       return HASH_SIZE_SHA224;
+}
+
+/**
  * Implementation of hasher_t.get_hash_size for SHA256.
  */
 static size_t get_hash_size256(private_sha256_hasher_t *this)
@@ -548,6 +595,16 @@ static size_t get_hash_size512(private_sha512_hasher_t *this)
 }
 
 /**
+ * Implementation of hasher_t.reset for SHA224
+ */
+static void reset224(private_sha256_hasher_t *ctx)
+{
+       memcpy(&ctx->sha_H[0], &sha224_hashInit[0], sizeof(ctx->sha_H));
+       ctx->sha_blocks = 0;
+       ctx->sha_bufCnt = 0;
+}
+
+/**
  * Implementation of hasher_t.reset for SHA256
  */
 static void reset256(private_sha256_hasher_t *ctx)
@@ -596,6 +653,13 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
        
        switch (algorithm)
        {
+               case HASH_SHA224:
+                       this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
+                       this->hasher_interface.reset = (void(*)(hasher_t*))reset224;
+                       this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size224;
+                       this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash224;
+                       this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash224;
+                       break;
                case HASH_SHA256:
                        this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
                        this->hasher_interface.reset = (void(*)(hasher_t*))reset256;
index 21bc592..0743f7b 100644 (file)
@@ -50,6 +50,8 @@ plugin_t *plugin_create()
        
        this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
        
+       lib->crypto->add_hasher(lib->crypto, HASH_SHA224,
+                                                       (hasher_constructor_t)sha2_hasher_create);
        lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
                                                        (hasher_constructor_t)sha2_hasher_create);
        lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
index df5a9c9..b182dd8 100644 (file)
@@ -98,6 +98,9 @@ TEST_VECTOR_HASHER(md5_7)
 TEST_VECTOR_HASHER(sha1_1)
 TEST_VECTOR_HASHER(sha1_2)
 TEST_VECTOR_HASHER(sha1_3)
+TEST_VECTOR_HASHER(sha224_1)
+TEST_VECTOR_HASHER(sha224_2)
+TEST_VECTOR_HASHER(sha224_3)
 TEST_VECTOR_HASHER(sha256_1)
 TEST_VECTOR_HASHER(sha256_2)
 TEST_VECTOR_HASHER(sha256_3)
index e2bd422..4679c26 100644 (file)
 #include <crypto/crypto_tester.h>
 
 /**
+ * SHA-224 vectors from "The Secure Hash Algorithm Validation System (SHAVS)"
+ */
+hasher_test_vector_t sha224_1 = {
+       .alg = HASH_SHA224, .len = 1,
+       .data   = "\x07",
+       .hash   = "\x00\xec\xd5\xf1\x38\x42\x2b\x8a\xd7\x4c\x97\x99\xfd\x82\x6c\x53"
+                         "\x1b\xad\x2f\xca\xbc\x74\x50\xbe\xe2\xaa\x8c\x2a"
+
+};
+
+hasher_test_vector_t sha224_2 = {
+       .alg = HASH_SHA224, .len = 16,
+       .data   = "\x18\x80\x40\x05\xdd\x4f\xbd\x15\x56\x29\x9d\x6f\x9d\x93\xdf\x62",
+       .hash   = "\xdf\x90\xd7\x8a\xa7\x88\x21\xc9\x9b\x40\xba\x4c\x96\x69\x21\xac"
+                         "\xcd\x8f\xfb\x1e\x98\xac\x38\x8e\x56\x19\x1d\xb1"
+};
+
+hasher_test_vector_t sha224_3 = {
+       .alg = HASH_SHA224, .len = 163,
+       .data   = "\x55\xb2\x10\x07\x9c\x61\xb5\x3a\xdd\x52\x06\x22\xd1\xac\x97\xd5"
+                         "\xcd\xbe\x8c\xb3\x3a\xa0\xae\x34\x45\x17\xbe\xe4\xd7\xba\x09\xab"
+                         "\xc8\x53\x3c\x52\x50\x88\x7a\x43\xbe\xbb\xac\x90\x6c\x2e\x18\x37"
+                         "\xf2\x6b\x36\xa5\x9a\xe3\xbe\x78\x14\xd5\x06\x89\x6b\x71\x8b\x2a"
+                         "\x38\x3e\xcd\xac\x16\xb9\x61\x25\x55\x3f\x41\x6f\xf3\x2c\x66\x74"
+                         "\xc7\x45\x99\xa9\x00\x53\x86\xd9\xce\x11\x12\x24\x5f\x48\xee\x47"
+                         "\x0d\x39\x6c\x1e\xd6\x3b\x92\x67\x0c\xa5\x6e\xc8\x4d\xee\xa8\x14"
+                         "\xb6\x13\x5e\xca\x54\x39\x2b\xde\xdb\x94\x89\xbc\x9b\x87\x5a\x8b"
+                         "\xaf\x0d\xc1\xae\x78\x57\x36\x91\x4a\xb7\xda\xa2\x64\xbc\x07\x9d"
+                         "\x26\x9f\x2c\x0d\x7e\xdd\xd8\x10\xa4\x26\x14\x5a\x07\x76\xf6\x7c"
+                         "\x87\x82\x73",
+       .hash   = "\x0b\x31\x89\x4e\xc8\x93\x7a\xd9\xb9\x1b\xdf\xbc\xba\x29\x4d\x9a"
+                         "\xde\xfa\xa1\x8e\x09\x30\x5e\x9f\x20\xd5\xc3\xa4"
+};
+
+/**
  * SHA-256 vectors from "The Secure Hash Algorithm Validation System (SHAVS)"
  */
 hasher_test_vector_t sha256_1 = {