OLD | NEW |
(Empty) | |
| 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. |
| 4 */ |
| 5 |
| 6 /* Routines for verifying a file's signature. Useful in testing the core |
| 7 * RSA verification implementation. |
| 8 */ |
| 9 |
| 10 #include <fcntl.h> |
| 11 #include <stdio.h> |
| 12 #include <stdlib.h> |
| 13 #include <string.h> |
| 14 #include <sys/stat.h> |
| 15 #include <sys/types.h> |
| 16 #include <unistd.h> |
| 17 |
| 18 #include "padding.h" |
| 19 #include "rsa.h" |
| 20 #include "sha.h" |
| 21 #include "verify_data.h" |
| 22 |
| 23 |
| 24 RSAPublicKey* read_RSAkey(char *input_file, int len) { |
| 25 int key_fd; |
| 26 RSAPublicKey *key = NULL; |
| 27 |
| 28 if ((key_fd = open(input_file, O_RDONLY)) == -1) { |
| 29 fprintf(stderr, "Couldn't open pre-processed key file\n"); |
| 30 return NULL; |
| 31 } |
| 32 |
| 33 key = (RSAPublicKey *) malloc(sizeof(RSAPublicKey)); |
| 34 if (!key) |
| 35 return NULL; |
| 36 |
| 37 /* Read the pre-processed RSA key into a RSAPublicKey structure */ |
| 38 /* TODO(gauravsh): Add error checking here? */ |
| 39 |
| 40 read(key_fd, &key->len, sizeof(key->len)); |
| 41 read(key_fd, &key->n0inv, sizeof(key->n0inv)); |
| 42 |
| 43 #ifndef NDEBUG |
| 44 fprintf(stderr, "%d\n", key->len); |
| 45 fprintf(stderr, "%d\n", key->n0inv); |
| 46 #endif |
| 47 |
| 48 key->n = (uint32_t *) malloc(len); |
| 49 read(key_fd, key->n, len); |
| 50 |
| 51 key->rr = (uint32_t *) malloc(len); |
| 52 read(key_fd, key->rr, len); |
| 53 |
| 54 #ifndef NDEBUG |
| 55 { |
| 56 int i; |
| 57 for(i=0; i<key->len; i++) { |
| 58 fprintf(stderr, "%d,", key->n[i]); |
| 59 } |
| 60 fprintf(stderr, "\n"); |
| 61 |
| 62 for(i=0; i<key->len; i++) { |
| 63 fprintf(stderr, "%d,", key->rr[i]); |
| 64 } |
| 65 fprintf(stderr, "\n"); |
| 66 } |
| 67 #endif |
| 68 |
| 69 close(key_fd); |
| 70 return key; |
| 71 } |
| 72 |
| 73 uint8_t* SHA1_file(char *input_file) { |
| 74 int i, input_fd, len; |
| 75 uint8_t data[SHA1_BLOCK_SIZE], *digest = NULL, *p = NULL; |
| 76 SHA1_CTX ctx; |
| 77 |
| 78 if( (input_fd = open(input_file, O_RDONLY)) == -1 ) { |
| 79 fprintf(stderr, "Couldn't open input file.\n"); |
| 80 return NULL; |
| 81 } |
| 82 |
| 83 /* Calculate SHA1 hash of input blocks, reading one block at a time. */ |
| 84 SHA1_init(&ctx); |
| 85 while ( (len = read(input_fd, data, SHA1_BLOCK_SIZE)) == SHA1_BLOCK_SIZE) |
| 86 SHA1_update(&ctx, data, len); |
| 87 if (len != -1) |
| 88 SHA1_update(&ctx, data, len); |
| 89 p = SHA1_final(&ctx); |
| 90 close(input_fd); |
| 91 |
| 92 digest = (uint8_t*) malloc(SHA1_DIGEST_SIZE); |
| 93 if (!digest) |
| 94 return NULL; |
| 95 for (i=0; i < SHA1_DIGEST_SIZE; i++) |
| 96 digest[i] = *p++; |
| 97 |
| 98 return digest; |
| 99 } |
| 100 |
| 101 uint8_t* SHA256_file(char *input_file) { |
| 102 int i, input_fd, len; |
| 103 uint8_t data[SHA256_BLOCK_SIZE], *digest = NULL, *p = NULL; |
| 104 SHA256_CTX ctx; |
| 105 |
| 106 if( (input_fd = open(input_file, O_RDONLY)) == -1 ) { |
| 107 fprintf(stderr, "Couldn't open input file.\n"); |
| 108 return NULL; |
| 109 } |
| 110 |
| 111 /* Calculate SHA256 hash of file, reading one block at a time. */ |
| 112 SHA256_init(&ctx); |
| 113 while ( (len = read(input_fd, data, SHA256_BLOCK_SIZE)) == SHA256_BLOCK_SIZE) |
| 114 SHA256_update(&ctx, data, len); |
| 115 if (len != -1) |
| 116 SHA256_update(&ctx, data, len); |
| 117 p = SHA256_final(&ctx); |
| 118 close(input_fd); |
| 119 |
| 120 digest = (uint8_t*) malloc(SHA256_DIGEST_SIZE); |
| 121 if (!digest) |
| 122 return NULL; |
| 123 for (i=0; i < SHA256_DIGEST_SIZE; i++) |
| 124 digest[i] = *p++; |
| 125 |
| 126 return digest; |
| 127 } |
| 128 |
| 129 uint8_t* SHA512_file(char* input_file) { |
| 130 int input_fd; |
| 131 uint8_t data[SHA512_BLOCK_SIZE], *digest = NULL, *p = NULL; |
| 132 int i, len; |
| 133 SHA512_CTX ctx; |
| 134 |
| 135 if( (input_fd = open(input_file, O_RDONLY)) == -1 ) { |
| 136 fprintf(stderr, "Couldn't open input file.\n"); |
| 137 return NULL; |
| 138 } |
| 139 |
| 140 /* Calculate SHA512 hash of file, reading one block at a time. */ |
| 141 SHA512_init(&ctx); |
| 142 while ( (len = read(input_fd, data, SHA512_BLOCK_SIZE)) == SHA512_BLOCK_SIZE) |
| 143 SHA512_update(&ctx, data, len); |
| 144 if (len != -1) |
| 145 SHA512_update(&ctx, data, len); |
| 146 p = SHA512_final(&ctx); |
| 147 close(input_fd); |
| 148 |
| 149 digest = (uint8_t*) malloc(SHA512_DIGEST_SIZE); |
| 150 if (!digest) |
| 151 return NULL; |
| 152 for (i=0; i < SHA512_DIGEST_SIZE; i++) |
| 153 digest[i] = *p++; |
| 154 |
| 155 return digest; |
| 156 } |
| 157 |
| 158 |
| 159 uint8_t* calculate_digest(char *input_file, int algorithm) { |
| 160 typedef uint8_t* (*Hash_file_ptr) (char*); |
| 161 Hash_file_ptr hash_file[] = { |
| 162 SHA1_file, /* RSA 1024 */ |
| 163 SHA256_file, |
| 164 SHA512_file, |
| 165 SHA1_file, /* RSA 2048 */ |
| 166 SHA256_file, |
| 167 SHA512_file, |
| 168 SHA1_file, /* RSA 4096 */ |
| 169 SHA256_file, |
| 170 SHA512_file, |
| 171 SHA1_file, /* RSA 8192 */ |
| 172 SHA256_file, |
| 173 SHA512_file, |
| 174 }; |
| 175 return hash_file[algorithm](input_file); |
| 176 } |
| 177 |
| 178 uint8_t* read_signature(char *input_file, int len) { |
| 179 int i, sigfd; |
| 180 uint8_t *signature = NULL; |
| 181 if ((sigfd = open(input_file, O_RDONLY)) == -1) { |
| 182 fprintf(stderr, "Couldn't open signature file\n"); |
| 183 return NULL; |
| 184 } |
| 185 |
| 186 /* Read the signature into a buffer*/ |
| 187 signature = (uint8_t*) malloc(len); |
| 188 if (!signature) |
| 189 return NULL; |
| 190 |
| 191 if( (i = read(sigfd, signature, len)) != len ) { |
| 192 fprintf(stderr, "Wrong signature length - Expected = %d, Received = %d\n", |
| 193 len, i); |
| 194 close(sigfd); |
| 195 return NULL; |
| 196 } |
| 197 |
| 198 close(sigfd); |
| 199 return signature; |
| 200 } |
| 201 |
| 202 |
| 203 int main(int argc, char* argv[]) { |
| 204 int i, algorithm, sig_len; |
| 205 uint8_t *digest = NULL, *signature = NULL; |
| 206 RSAPublicKey* key = NULL; |
| 207 |
| 208 if (argc!=5) { |
| 209 fprintf(stderr, "Usage: %s <algorithm> <key file> <signature file>" |
| 210 " <input file>\n\n", argv[0]); |
| 211 fprintf(stderr, "where <algorithm> depends on the signature algorithm" |
| 212 " used:\n"); |
| 213 for(i = 0; i<kNumAlgorithms; i++) |
| 214 fprintf(stderr, "\t%d for %s\n", i, algo_strings[i]); |
| 215 return -1; |
| 216 } |
| 217 |
| 218 algorithm = atoi(argv[1]); |
| 219 if (algorithm >= kNumAlgorithms) { |
| 220 fprintf(stderr, "Invalid Algorithm!\n"); |
| 221 return 0; |
| 222 } |
| 223 /* Length of the RSA Signature/RSA Key */ |
| 224 sig_len = siglen_map[algorithm] * sizeof(uint32_t); |
| 225 |
| 226 if (!(key = read_RSAkey(argv[2], sig_len))) |
| 227 goto failure; |
| 228 if (!(signature = read_signature(argv[3], sig_len))) |
| 229 goto failure; |
| 230 if (!(digest = calculate_digest(argv[4], algorithm))) |
| 231 goto failure; |
| 232 if(RSA_verify(key, signature, sig_len, algorithm, digest)) |
| 233 fprintf(stderr, "Signature Verification SUCCEEDED.\n"); |
| 234 else |
| 235 fprintf(stderr, "Signature Verification FAILED!\n"); |
| 236 |
| 237 failure: |
| 238 free(key); |
| 239 free(signature); |
| 240 free(digest); |
| 241 |
| 242 return 0; |
| 243 } |
OLD | NEW |