aboutsummaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2015-04-12 14:50:18 +0100
committerMichael Brown <mcb30@ipxe.org>2015-04-12 17:01:10 +0100
commit4dbc44348ca9011465c3bce38757173c059309ec (patch)
treec5f0790a71bc74fe3083a18e164416b0ecf3ed4b /src/crypto
parenta9da1291227735fdae475e21b02b2a5fa29dd956 (diff)
downloadipxe-4dbc44348ca9011465c3bce38757173c059309ec.zip
ipxe-4dbc44348ca9011465c3bce38757173c059309ec.tar.gz
ipxe-4dbc44348ca9011465c3bce38757173c059309ec.tar.bz2
[crypto] Add SHA-224 algorithm
SHA-224 is almost identical to SHA-256, with differing initial hash values and a truncated output length. This implementation has been verified using the NIST SHA-224 test vectors. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/sha224.c82
-rw-r--r--src/crypto/sha256.c49
2 files changed, 118 insertions, 13 deletions
diff --git a/src/crypto/sha224.c b/src/crypto/sha224.c
new file mode 100644
index 0000000..be25f24
--- /dev/null
+++ b/src/crypto/sha224.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * 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 Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+/** @file
+ *
+ * SHA-224 algorithm
+ *
+ */
+
+#include <stdint.h>
+#include <byteswap.h>
+#include <ipxe/crypto.h>
+#include <ipxe/asn1.h>
+#include <ipxe/sha256.h>
+
+/** SHA-224 initial digest values */
+static const struct sha256_digest sha224_init_digest = {
+ .h = {
+ cpu_to_be32 ( 0xc1059ed8 ),
+ cpu_to_be32 ( 0x367cd507 ),
+ cpu_to_be32 ( 0x3070dd17 ),
+ cpu_to_be32 ( 0xf70e5939 ),
+ cpu_to_be32 ( 0xffc00b31 ),
+ cpu_to_be32 ( 0x68581511 ),
+ cpu_to_be32 ( 0x64f98fa7 ),
+ cpu_to_be32 ( 0xbefa4fa4 ),
+ },
+};
+
+/**
+ * Initialise SHA-224 algorithm
+ *
+ * @v ctx SHA-224 context
+ */
+static void sha224_init ( void *ctx ) {
+ struct sha256_context *context = ctx;
+
+ sha256_family_init ( context, &sha224_init_digest, SHA224_DIGEST_SIZE );
+}
+
+/** SHA-224 algorithm */
+struct digest_algorithm sha224_algorithm = {
+ .name = "sha224",
+ .ctxsize = sizeof ( struct sha256_context ),
+ .blocksize = sizeof ( union sha256_block ),
+ .digestsize = SHA224_DIGEST_SIZE,
+ .init = sha224_init,
+ .update = sha256_update,
+ .final = sha256_final,
+};
+
+/** "sha224" object identifier */
+static uint8_t oid_sha224[] = { ASN1_OID_SHA224 };
+
+/** "sha224" OID-identified algorithm */
+struct asn1_algorithm oid_sha224_algorithm __asn1_algorithm = {
+ .name = "sha224",
+ .digest = &sha224_algorithm,
+ .oid = ASN1_OID_CURSOR ( oid_sha224 ),
+};
diff --git a/src/crypto/sha256.c b/src/crypto/sha256.c
index 3a56056..695ae70 100644
--- a/src/crypto/sha256.c
+++ b/src/crypto/sha256.c
@@ -69,6 +69,37 @@ static const uint32_t k[64] = {
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
+/** SHA-256 initial digest values */
+static const struct sha256_digest sha256_init_digest = {
+ .h = {
+ cpu_to_be32 ( 0x6a09e667 ),
+ cpu_to_be32 ( 0xbb67ae85 ),
+ cpu_to_be32 ( 0x3c6ef372 ),
+ cpu_to_be32 ( 0xa54ff53a ),
+ cpu_to_be32 ( 0x510e527f ),
+ cpu_to_be32 ( 0x9b05688c ),
+ cpu_to_be32 ( 0x1f83d9ab ),
+ cpu_to_be32 ( 0x5be0cd19 ),
+ },
+};
+
+/**
+ * Initialise SHA-256 family algorithm
+ *
+ * @v context SHA-256 context
+ * @v init Initial digest values
+ * @v digestsize Digest size
+ */
+void sha256_family_init ( struct sha256_context *context,
+ const struct sha256_digest *init,
+ size_t digestsize ) {
+
+ context->len = 0;
+ context->digestsize = digestsize;
+ memcpy ( &context->ddd.dd.digest, init,
+ sizeof ( context->ddd.dd.digest ) );
+}
+
/**
* Initialise SHA-256 algorithm
*
@@ -77,15 +108,8 @@ static const uint32_t k[64] = {
static void sha256_init ( void *ctx ) {
struct sha256_context *context = ctx;
- context->ddd.dd.digest.h[0] = cpu_to_be32 ( 0x6a09e667 );
- context->ddd.dd.digest.h[1] = cpu_to_be32 ( 0xbb67ae85 );
- context->ddd.dd.digest.h[2] = cpu_to_be32 ( 0x3c6ef372 );
- context->ddd.dd.digest.h[3] = cpu_to_be32 ( 0xa54ff53a );
- context->ddd.dd.digest.h[4] = cpu_to_be32 ( 0x510e527f );
- context->ddd.dd.digest.h[5] = cpu_to_be32 ( 0x9b05688c );
- context->ddd.dd.digest.h[6] = cpu_to_be32 ( 0x1f83d9ab );
- context->ddd.dd.digest.h[7] = cpu_to_be32 ( 0x5be0cd19 );
- context->len = 0;
+ sha256_family_init ( context, &sha256_init_digest,
+ sizeof ( struct sha256_digest ) );
}
/**
@@ -190,7 +214,7 @@ static void sha256_digest ( struct sha256_context *context ) {
* @v data Data
* @v len Length of data
*/
-static void sha256_update ( void *ctx, const void *data, size_t len ) {
+void sha256_update ( void *ctx, const void *data, size_t len ) {
struct sha256_context *context = ctx;
const uint8_t *byte = data;
size_t offset;
@@ -213,7 +237,7 @@ static void sha256_update ( void *ctx, const void *data, size_t len ) {
* @v ctx SHA-256 context
* @v out Output buffer
*/
-static void sha256_final ( void *ctx, void *out ) {
+void sha256_final ( void *ctx, void *out ) {
struct sha256_context *context = ctx;
uint64_t len_bits;
uint8_t pad;
@@ -234,8 +258,7 @@ static void sha256_final ( void *ctx, void *out ) {
assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
/* Copy out final digest */
- memcpy ( out, &context->ddd.dd.digest,
- sizeof ( context->ddd.dd.digest ) );
+ memcpy ( out, &context->ddd.dd.digest, context->digestsize );
}
/** SHA-256 algorithm */