diff --git a/crypto/Makefile b/crypto/Makefile index ff4326df71..b6d654f4d0 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -SRCS=rsa.c sha1.c sha2.c padding.c rsa_utility.c +SRCS=rsa.c sha1.c sha2.c padding.c rsa_utility.c sha_utility.c OBJS=$(SRCS:.c=.o) all: libcrypto.a diff --git a/crypto/sha_utility.c b/crypto/sha_utility.c new file mode 100644 index 0000000000..5e3f7e07c4 --- /dev/null +++ b/crypto/sha_utility.c @@ -0,0 +1,133 @@ +/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Utility functions for message digest functions. + */ + +#include "sha_utility.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "sha.h" +#include "utility.h" + +int digest_type_map[] = { + SHA1_DIGEST_ALGORITHM, /* RSA 1024 */ + SHA256_DIGEST_ALGORITHM, + SHA512_DIGEST_ALGORITHM, + SHA1_DIGEST_ALGORITHM, /* RSA 2048 */ + SHA256_DIGEST_ALGORITHM, + SHA512_DIGEST_ALGORITHM, + SHA1_DIGEST_ALGORITHM, /* RSA 4096 */ + SHA256_DIGEST_ALGORITHM, + SHA512_DIGEST_ALGORITHM, + SHA1_DIGEST_ALGORITHM, /* RSA 8192 */ + SHA256_DIGEST_ALGORITHM, + SHA512_DIGEST_ALGORITHM, +}; + +void DigestInit(DigestContext* ctx, int sig_algorithm) { + ctx->algorithm = digest_type_map[sig_algorithm]; + switch(ctx->algorithm) { + case SHA1_DIGEST_ALGORITHM: + ctx->sha1_ctx = (SHA1_CTX*) Malloc(sizeof(SHA1_CTX)); + SHA1_init(ctx->sha1_ctx); + break; + case SHA256_DIGEST_ALGORITHM: + ctx->sha256_ctx = (SHA256_CTX*) Malloc(sizeof(SHA256_CTX)); + SHA256_init(ctx->sha256_ctx); + break; + case SHA512_DIGEST_ALGORITHM: + ctx->sha512_ctx = (SHA512_CTX*) Malloc(sizeof(SHA512_CTX)); + SHA512_init(ctx->sha512_ctx); + break; + }; +} + +void DigestUpdate(DigestContext* ctx, const uint8_t* data, int len) { + switch(ctx->algorithm) { + case SHA1_DIGEST_ALGORITHM: + SHA1_update(ctx->sha1_ctx, data, len); + break; + case SHA256_DIGEST_ALGORITHM: + SHA256_update(ctx->sha256_ctx, data, len); + break; + case SHA512_DIGEST_ALGORITHM: + SHA512_update(ctx->sha512_ctx, data, len); + break; + }; +} + +uint8_t* DigestFinal(DigestContext* ctx) { + uint8_t* digest = NULL; + switch(ctx->algorithm) { + case SHA1_DIGEST_ALGORITHM: + digest = (uint8_t*) Malloc(SHA1_DIGEST_SIZE); + Memcpy(digest, SHA1_final(ctx->sha1_ctx), SHA1_DIGEST_SIZE); + Free(ctx->sha1_ctx); + break; + case SHA256_DIGEST_ALGORITHM: + digest = (uint8_t*) Malloc(SHA256_DIGEST_SIZE); + Memcpy(digest, SHA256_final(ctx->sha256_ctx), SHA256_DIGEST_SIZE); + Free(ctx->sha256_ctx); + break; + case SHA512_DIGEST_ALGORITHM: + digest = (uint8_t*) Malloc(SHA512_DIGEST_SIZE); + Memcpy(digest, SHA512_final(ctx->sha512_ctx), SHA512_DIGEST_SIZE); + Free(ctx->sha512_ctx); + break; + }; + return digest; +} + +uint8_t* DigestFile(char* input_file, int sig_algorithm) { + int input_fd, len; + uint8_t data[SHA1_BLOCK_SIZE]; + uint8_t* digest = NULL; + DigestContext ctx; + + if( (input_fd = open(input_file, O_RDONLY)) == -1 ) { + fprintf(stderr, "Couldn't open input file.\n"); + return NULL; + } + DigestInit(&ctx, sig_algorithm); + while ( (len = read(input_fd, data, SHA1_BLOCK_SIZE)) == + SHA1_BLOCK_SIZE) + DigestUpdate(&ctx, data, len); + if (len != -1) + DigestUpdate(&ctx, data, len); + digest = DigestFinal(&ctx); + close(input_fd); + return digest; +} + +uint8_t* DigestBuf(uint8_t* buf, int len, int sig_algorithm) { + uint8_t* digest = (uint8_t*) Malloc(SHA512_DIGEST_SIZE); /* Use the max. */ + /* Define an array mapping [sig_algorithm] to function pointers to the + * SHA{1|256|512} functions. + */ + typedef uint8_t* (*Hash_ptr) (const uint8_t*, int, uint8_t*); + Hash_ptr hash[] = { + SHA1, /* RSA 1024 */ + SHA256, + SHA512, + SHA1, /* RSA 2048 */ + SHA256, + SHA512, + SHA1, /* RSA 4096 */ + SHA256, + SHA512, + SHA1, /* RSA 8192 */ + SHA256, + SHA512, + }; + /* Call the appropriate hash function. */ + return hash[sig_algorithm](buf, len, digest); +} diff --git a/include/sha_utility.h b/include/sha_utility.h new file mode 100644 index 0000000000..d786b08487 --- /dev/null +++ b/include/sha_utility.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Utility functions for message digests. +*/ + +#ifndef VBOOT_REFERENCE_SHA_UTILITY_H_ +#define VBOOT_REFERENCE_SHA_UTILITY_H_ + +#include + +#include "sha.h" + +#define SHA1_DIGEST_ALGORITHM 0 +#define SHA256_DIGEST_ALGORITHM 1 +#define SHA512_DIGEST_ALGORITHM 2 + +/* A generic digest context structure which can be used to represent + * the SHA*_CTX for multiple digest algorithms. + */ +typedef struct DigestContext { + SHA1_CTX* sha1_ctx; + SHA256_CTX* sha256_ctx; + SHA512_CTX* sha512_ctx; + int algorithm; /* Hashing algorithm to use. */ +} DigestContext; + +/* Wrappers for message digest algorithms. These are useful when the hashing + * operation is being done in parallel with something else. DigestContext tracks + * and stores the state of any digest algorithm (one at any given time). + */ + +/* Initialize a digest context for use with signature algorithm [algorithm]. */ +void DigestInit(DigestContext* ctx, int sig_algorithm); +void DigestUpdate(DigestContext* ctx, const uint8_t* data, int len); + +/* Caller owns the returned digest and must free it. */ +uint8_t* DigestFinal(DigestContext* ctx); + +/* Returns the appropriate digest for the data in [input_file] + * based on the signature [algorithm]. + * Caller owns the returned digest and must free it. + */ +uint8_t* DigestFile(char* input_file, int sig_algorithm); + +/* Returns the appropriate digest of [buf] of length + * [len] based on the signature [algorithm]. + * Caller owns the returned digest and must free it. + */ +uint8_t* DigestBuf(uint8_t* buf, int len, int sig_algorithm); + +#endif /* VBOOT_REFERENCE_SHA_UTILITY_H_ */ diff --git a/tests/Makefile b/tests/Makefile index 7e2601d1c4..ba50eccbd9 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -SRCS=sha_tests.c verify_data.c digest_utility.c signature_digest.c +SRCS=sha_tests.c verify_data.c signature_digest.c OBJS=$(SRCS:.c=.o) LIBS=$(TOP)/crypto/libcrypto.a $(TOP)/common/libcommon.a @@ -12,12 +12,9 @@ sha_tests: sha_tests.c $(CC) $(CFLAGS) -DNDEBUG $(INCLUDES) $< -o $@ $(LIBS) verify_data: verify_data.c digest_utility.o - $(CC) $(CFLAGS) -DNDEBUG $(INCLUDES) $< -o $@ digest_utility.o $(LIBS) + $(CC) $(CFLAGS) -DNDEBUG $(INCLUDES) $< -o $@ $(LIBS) -signature_digest: signature_digest.c digest_utility.o - $(CC) $(CFLAGS) -DNDEBUG $(INCLUDES) $< -o $@ digest_utility.o $(LIBS) - -digest_utility.o: digest_utility.c - $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ +signature_digest: signature_digest.c + $(CC) $(CFLAGS) -DNDEBUG $(INCLUDES) $< -o $@ $(LIBS) clean: rm -f $(OBJS) sha_tests verify_data signature_digest diff --git a/tests/digest_utility.c b/tests/digest_utility.c deleted file mode 100644 index 81e7cafc36..0000000000 --- a/tests/digest_utility.c +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Utility functions for message digest functions. - */ - -#include "digest_utility.h" -#include "sha.h" - -#include -#include -#include -#include -#include -#include -#include - -uint8_t* SHA1_file(char* input_file) { - int input_fd, len; - uint8_t data[ SHA1_BLOCK_SIZE], *digest = NULL, *p = NULL; - SHA1_CTX ctx; - if( (input_fd = open(input_file, O_RDONLY)) == -1 ) { - fprintf(stderr, "Couldn't open input file.\n"); - return NULL; - } - SHA1_init(&ctx); - while ( (len = read(input_fd, data, SHA1_BLOCK_SIZE)) == - SHA1_BLOCK_SIZE) - SHA1_update(&ctx, data, len); - if (len != -1) - SHA1_update(&ctx, data, len); - p = SHA1_final(&ctx); - close(input_fd); - digest = (uint8_t*) malloc(SHA1_DIGEST_SIZE); - if (!digest) - return NULL; - memcpy(digest, p, SHA1_DIGEST_SIZE); - return digest; -} - -uint8_t* SHA256_file(char* input_file) { - int input_fd, len; - uint8_t data[ SHA256_BLOCK_SIZE], *digest = NULL, *p = NULL; - SHA256_CTX ctx; - if( (input_fd = open(input_file, O_RDONLY)) == -1 ) { - fprintf(stderr, "Couldn't open input file.\n"); - return NULL; - } - SHA256_init(&ctx); - while ( (len = read(input_fd, data, SHA256_BLOCK_SIZE)) == - SHA256_BLOCK_SIZE) - SHA256_update(&ctx, data, len); - if (len != -1) - SHA256_update(&ctx, data, len); - p = SHA256_final(&ctx); - close(input_fd); - digest = (uint8_t*) malloc(SHA256_DIGEST_SIZE); - if (!digest) - return NULL; - memcpy(digest, p, SHA256_DIGEST_SIZE); - return digest; -} - -uint8_t* SHA512_file(char* input_file) { - int input_fd, len; - uint8_t data[ SHA512_BLOCK_SIZE], *digest = NULL, *p = NULL; - SHA512_CTX ctx; - if( (input_fd = open(input_file, O_RDONLY)) == -1 ) { - fprintf(stderr, "Couldn't open input file.\n"); - return NULL; - } - SHA512_init(&ctx); - while ( (len = read(input_fd, data, SHA512_BLOCK_SIZE)) == - SHA512_BLOCK_SIZE) - SHA512_update(&ctx, data, len); - if (len != -1) - SHA512_update(&ctx, data, len); - p = SHA512_final(&ctx); - close(input_fd); - digest = (uint8_t*) malloc(SHA512_DIGEST_SIZE); - if (!digest) - return NULL; - memcpy(digest, p, SHA512_DIGEST_SIZE); - return digest; -} - -uint8_t* calculate_digest(char *input_file, int algorithm) { - typedef uint8_t* (*Hash_file_ptr) (char*); - Hash_file_ptr hash_file[] = { - SHA1_file, /* RSA 1024 */ - SHA256_file, - SHA512_file, - SHA1_file, /* RSA 2048 */ - SHA256_file, - SHA512_file, - SHA1_file, /* RSA 4096 */ - SHA256_file, - SHA512_file, - SHA1_file, /* RSA 8192 */ - SHA256_file, - SHA512_file, - }; - return hash_file[algorithm](input_file); -} diff --git a/tests/digest_utility.h b/tests/digest_utility.h deleted file mode 100644 index 9d59efb19f..0000000000 --- a/tests/digest_utility.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Utility functions for message digest functions. */ - -#ifndef VBOOT_REFERENCE_DIGEST_UTILITY_H_ -#define VBOOT_REFERENCE_DIGEST_UTILITY_H_ - -#include - -/* Returns the SHA-1 digest of data in [input_file]. - * Caller owns the returned digest and must free it. - */ -uint8_t* SHA1_file(char *input_file); - -/* Returns the SHA-256 digest of data in [input_file]. - * Caller owns the returned digest and must free it. - */ -uint8_t* SHA256_file(char *input_file); - -/* Returns the SHA-512 digest of data in [input_file]. - * Caller owns the returned digest and must free it. - */ -uint8_t* SHA512_file(char *input_file); - -/* Returns the appropriate digest for the data in [input_file] - * based on the signature [algorithm]. - * Caller owns the returned digest and must free it. - */ -uint8_t* calculate_digest(char *input_file, int algorithm); - -#endif /* VBOOT_REFERENCE_DIGEST_UTILITY_H_ */ diff --git a/tests/signature_digest.c b/tests/signature_digest.c index 89d98fe120..8dcd8c91e5 100644 --- a/tests/signature_digest.c +++ b/tests/signature_digest.c @@ -17,9 +17,9 @@ #include #include -#include "digest_utility.h" #include "padding.h" #include "sha.h" +#include "sha_utility.h" uint8_t* prepend_digestinfo(int algorithm, uint8_t* digest) { const int digest_size = hash_size_map[algorithm]; @@ -52,7 +52,7 @@ int main(int argc, char* argv[]) { goto failure; } - if (!(digest = calculate_digest(argv[2], algorithm))) + if (!(digest = DigestFile(argv[2], algorithm))) goto failure; info_digest = prepend_digestinfo(algorithm, digest); diff --git a/tests/verify_data.c b/tests/verify_data.c index ac51dafaf1..0f0dc02689 100644 --- a/tests/verify_data.c +++ b/tests/verify_data.c @@ -15,7 +15,7 @@ #include #include -#include "digest_utility.h" +#include "sha_utility.h" #include "padding.h" #include "rsa.h" #include "rsa_utility.h" @@ -23,9 +23,7 @@ RSAPublicKey* read_RSAkey(char* input_file, int len) { int key_fd; - int buf_len; - struct stat stat_fd; - uint8_t* buf = NULL; + RSAPublicKey* key = NULL; if ((key_fd = open(input_file, O_RDONLY)) == -1) { fprintf(stderr, "Couldn't open pre-processed key file\n"); @@ -105,7 +103,7 @@ int main(int argc, char* argv[]) { goto failure; if (!(signature = read_signature(argv[3], sig_len))) goto failure; - if (!(digest = calculate_digest(argv[4], algorithm))) + if (!(digest = DigestFile(argv[4], algorithm))) goto failure; if(RSA_verify(key, signature, sig_len, algorithm, digest)) fprintf(stderr, "Signature Verification SUCCEEDED.\n");