Index: src/platform/vboot_reference/tests/verify_data.c |
diff --git a/src/platform/vboot_reference/tests/verify_data.c b/src/platform/vboot_reference/tests/verify_data.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d5b1c99d24693c5d3220ac6d0ca0218a4e0b0e00 |
--- /dev/null |
+++ b/src/platform/vboot_reference/tests/verify_data.c |
@@ -0,0 +1,243 @@ |
+/* 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. |
+ */ |
+ |
+/* Routines for verifying a file's signature. Useful in testing the core |
+ * RSA verification implementation. |
+ */ |
+ |
+#include <fcntl.h> |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+#include <sys/stat.h> |
+#include <sys/types.h> |
+#include <unistd.h> |
+ |
+#include "padding.h" |
+#include "rsa.h" |
+#include "sha.h" |
+#include "verify_data.h" |
+ |
+ |
+RSAPublicKey* read_RSAkey(char *input_file, int len) { |
+ int key_fd; |
+ RSAPublicKey *key = NULL; |
+ |
+ if ((key_fd = open(input_file, O_RDONLY)) == -1) { |
+ fprintf(stderr, "Couldn't open pre-processed key file\n"); |
+ return NULL; |
+ } |
+ |
+ key = (RSAPublicKey *) malloc(sizeof(RSAPublicKey)); |
+ if (!key) |
+ return NULL; |
+ |
+ /* Read the pre-processed RSA key into a RSAPublicKey structure */ |
+ /* TODO(gauravsh): Add error checking here? */ |
+ |
+ read(key_fd, &key->len, sizeof(key->len)); |
+ read(key_fd, &key->n0inv, sizeof(key->n0inv)); |
+ |
+#ifndef NDEBUG |
+ fprintf(stderr, "%d\n", key->len); |
+ fprintf(stderr, "%d\n", key->n0inv); |
+#endif |
+ |
+ key->n = (uint32_t *) malloc(len); |
+ read(key_fd, key->n, len); |
+ |
+ key->rr = (uint32_t *) malloc(len); |
+ read(key_fd, key->rr, len); |
+ |
+#ifndef NDEBUG |
+ { |
+ int i; |
+ for(i=0; i<key->len; i++) { |
+ fprintf(stderr, "%d,", key->n[i]); |
+ } |
+ fprintf(stderr, "\n"); |
+ |
+ for(i=0; i<key->len; i++) { |
+ fprintf(stderr, "%d,", key->rr[i]); |
+ } |
+ fprintf(stderr, "\n"); |
+ } |
+#endif |
+ |
+ close(key_fd); |
+ return key; |
+} |
+ |
+uint8_t* SHA1_file(char *input_file) { |
+ int i, 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; |
+ } |
+ |
+ /* Calculate SHA1 hash of input blocks, reading one block at a time. */ |
+ 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; |
+ for (i=0; i < SHA1_DIGEST_SIZE; i++) |
+ digest[i] = *p++; |
+ |
+ return digest; |
+} |
+ |
+uint8_t* SHA256_file(char *input_file) { |
+ int i, 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; |
+ } |
+ |
+ /* Calculate SHA256 hash of file, reading one block at a time. */ |
+ 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; |
+ for (i=0; i < SHA256_DIGEST_SIZE; i++) |
+ digest[i] = *p++; |
+ |
+ return digest; |
+} |
+ |
+uint8_t* SHA512_file(char* input_file) { |
+ int input_fd; |
+ uint8_t data[SHA512_BLOCK_SIZE], *digest = NULL, *p = NULL; |
+ int i, len; |
+ SHA512_CTX ctx; |
+ |
+ if( (input_fd = open(input_file, O_RDONLY)) == -1 ) { |
+ fprintf(stderr, "Couldn't open input file.\n"); |
+ return NULL; |
+ } |
+ |
+ /* Calculate SHA512 hash of file, reading one block at a time. */ |
+ 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; |
+ for (i=0; i < SHA512_DIGEST_SIZE; i++) |
+ digest[i] = *p++; |
+ |
+ 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); |
+} |
+ |
+uint8_t* read_signature(char *input_file, int len) { |
+ int i, sigfd; |
+ uint8_t *signature = NULL; |
+ if ((sigfd = open(input_file, O_RDONLY)) == -1) { |
+ fprintf(stderr, "Couldn't open signature file\n"); |
+ return NULL; |
+ } |
+ |
+ /* Read the signature into a buffer*/ |
+ signature = (uint8_t*) malloc(len); |
+ if (!signature) |
+ return NULL; |
+ |
+ if( (i = read(sigfd, signature, len)) != len ) { |
+ fprintf(stderr, "Wrong signature length - Expected = %d, Received = %d\n", |
+ len, i); |
+ close(sigfd); |
+ return NULL; |
+ } |
+ |
+ close(sigfd); |
+ return signature; |
+} |
+ |
+ |
+int main(int argc, char* argv[]) { |
+ int i, algorithm, sig_len; |
+ uint8_t *digest = NULL, *signature = NULL; |
+ RSAPublicKey* key = NULL; |
+ |
+ if (argc!=5) { |
+ fprintf(stderr, "Usage: %s <algorithm> <key file> <signature file>" |
+ " <input file>\n\n", argv[0]); |
+ fprintf(stderr, "where <algorithm> depends on the signature algorithm" |
+ " used:\n"); |
+ for(i = 0; i<kNumAlgorithms; i++) |
+ fprintf(stderr, "\t%d for %s\n", i, algo_strings[i]); |
+ return -1; |
+ } |
+ |
+ algorithm = atoi(argv[1]); |
+ if (algorithm >= kNumAlgorithms) { |
+ fprintf(stderr, "Invalid Algorithm!\n"); |
+ return 0; |
+ } |
+ /* Length of the RSA Signature/RSA Key */ |
+ sig_len = siglen_map[algorithm] * sizeof(uint32_t); |
+ |
+ if (!(key = read_RSAkey(argv[2], sig_len))) |
+ goto failure; |
+ if (!(signature = read_signature(argv[3], sig_len))) |
+ goto failure; |
+ if (!(digest = calculate_digest(argv[4], algorithm))) |
+ goto failure; |
+ if(RSA_verify(key, signature, sig_len, algorithm, digest)) |
+ fprintf(stderr, "Signature Verification SUCCEEDED.\n"); |
+ else |
+ fprintf(stderr, "Signature Verification FAILED!\n"); |
+ |
+failure: |
+ free(key); |
+ free(signature); |
+ free(digest); |
+ |
+ return 0; |
+} |