OLD | NEW |
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 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 | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
4 * | 4 * |
5 * Host functions for keys. | 5 * Host functions for keys. |
6 */ | 6 */ |
7 | 7 |
8 /* TODO: change all 'return 0', 'return 1' into meaningful return codes */ | 8 /* TODO: change all 'return 0', 'return 1' into meaningful return codes */ |
9 | 9 |
10 #define OPENSSL_NO_SHA | 10 #define OPENSSL_NO_SHA |
11 #include <openssl/engine.h> | 11 #include <openssl/engine.h> |
12 #include <openssl/pem.h> | 12 #include <openssl/pem.h> |
13 #include <openssl/rsa.h> | 13 #include <openssl/rsa.h> |
14 | 14 |
15 #include <stdio.h> | 15 #include <stdio.h> |
16 #include <stdlib.h> | 16 #include <stdlib.h> |
17 #include <unistd.h> | 17 #include <unistd.h> |
18 | 18 |
19 #include "host_key.h" | 19 #include "host_key.h" |
20 | 20 |
21 #include "cryptolib.h" | 21 #include "cryptolib.h" |
22 #include "file_keys.h" | 22 #include "host_misc.h" |
23 #include "utility.h" | 23 #include "utility.h" |
24 #include "vboot_common.h" | 24 #include "vboot_common.h" |
25 | 25 |
26 | 26 |
27 VbPrivateKey* PrivateKeyRead(const char* filename, uint64_t algorithm) { | 27 VbPrivateKey* PrivateKeyRead(const char* filename, uint64_t algorithm) { |
28 | 28 |
29 VbPrivateKey* key; | 29 VbPrivateKey* key; |
30 RSA* rsa_key; | 30 RSA* rsa_key; |
31 FILE* f; | 31 FILE* f; |
32 | 32 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 73 |
74 | 74 |
75 void PublicKeyInit(VbPublicKey* key, uint8_t* key_data, uint64_t key_size) { | 75 void PublicKeyInit(VbPublicKey* key, uint8_t* key_data, uint64_t key_size) { |
76 key->key_offset = OffsetOf(key, key_data); | 76 key->key_offset = OffsetOf(key, key_data); |
77 key->key_size = key_size; | 77 key->key_size = key_size; |
78 key->algorithm = kNumAlgorithms; /* Key not present yet */ | 78 key->algorithm = kNumAlgorithms; /* Key not present yet */ |
79 key->key_version = 0; | 79 key->key_version = 0; |
80 } | 80 } |
81 | 81 |
82 | 82 |
| 83 /* Allocate a new public key with space for a [key_size] byte key. */ |
83 VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm, | 84 VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm, |
84 uint64_t version) { | 85 uint64_t version) { |
85 VbPublicKey* key = (VbPublicKey*)Malloc(sizeof(VbPublicKey) + key_size); | 86 VbPublicKey* key = (VbPublicKey*)Malloc(sizeof(VbPublicKey) + key_size); |
86 if (!key) | 87 if (!key) |
87 return NULL; | 88 return NULL; |
88 | 89 |
89 key->algorithm = algorithm; | 90 key->algorithm = algorithm; |
90 key->key_version = version; | 91 key->key_version = version; |
91 key->key_size = key_size; | 92 key->key_size = key_size; |
92 key->key_offset = sizeof(VbPublicKey); | 93 key->key_offset = sizeof(VbPublicKey); |
93 return key; | 94 return key; |
94 } | 95 } |
95 | 96 |
96 | 97 |
| 98 /* Copy a public key from [src] to [dest]. |
| 99 * |
| 100 * Returns zero if success, non-zero if error. */ |
97 int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src) { | 101 int PublicKeyCopy(VbPublicKey* dest, const VbPublicKey* src) { |
98 if (dest->key_size < src->key_size) | 102 if (dest->key_size < src->key_size) |
99 return 1; | 103 return 1; |
100 | 104 |
101 dest->key_size = src->key_size; | 105 dest->key_size = src->key_size; |
102 dest->algorithm = src->algorithm; | 106 dest->algorithm = src->algorithm; |
103 dest->key_version = src->key_version; | 107 dest->key_version = src->key_version; |
104 Memcpy(GetPublicKeyData(dest), GetPublicKeyDataC(src), src->key_size); | 108 Memcpy(GetPublicKeyData(dest), GetPublicKeyDataC(src), src->key_size); |
105 return 0; | 109 return 0; |
106 } | 110 } |
107 | 111 |
108 | 112 |
109 VbPublicKey* PublicKeyRead(const char* filename, uint64_t algorithm, | 113 VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm, |
110 uint64_t version) { | 114 uint64_t version) { |
111 | |
112 VbPublicKey* key; | 115 VbPublicKey* key; |
113 uint8_t* key_data; | 116 uint8_t* key_data; |
114 uint64_t key_size; | 117 uint64_t key_size; |
115 | 118 |
116 if (algorithm >= kNumAlgorithms) { | 119 if (algorithm >= kNumAlgorithms) { |
117 debug("PublicKeyRead() called with invalid algorithm!\n"); | 120 debug("PublicKeyReadKeyb() called with invalid algorithm!\n"); |
118 return NULL; | 121 return NULL; |
119 } | 122 } |
120 if (version > 0xFFFF) { | 123 if (version > 0xFFFF) { |
121 /* Currently, TPM only supports 16-bit version */ | 124 /* Currently, TPM only supports 16-bit version */ |
122 debug("PublicKeyRead() called with invalid version!\n"); | 125 debug("PublicKeyReadKeyb() called with invalid version!\n"); |
123 return NULL; | 126 return NULL; |
124 } | 127 } |
125 | 128 |
126 key_data = BufferFromFile(filename, &key_size); | 129 key_data = ReadFile(filename, &key_size); |
127 if (!key_data) | 130 if (!key_data) |
128 return NULL; | 131 return NULL; |
129 | 132 |
130 /* TODO: sanity-check key length based on algorithm */ | 133 if (RSAProcessedKeySize(algorithm) != key_size) { |
| 134 debug("PublicKeyReadKeyb() wrong key size for algorithm\n"); |
| 135 Free(key_data); |
| 136 return NULL; |
| 137 } |
131 | 138 |
132 key = PublicKeyAlloc(key_size, algorithm, version); | 139 key = PublicKeyAlloc(key_size, algorithm, version); |
133 if (!key) { | 140 if (!key) { |
134 Free(key_data); | 141 Free(key_data); |
135 return NULL; | 142 return NULL; |
136 } | 143 } |
137 Memcpy(GetPublicKeyData(key), key_data, key_size); | 144 Memcpy(GetPublicKeyData(key), key_data, key_size); |
138 | 145 |
139 Free(key_data); | 146 Free(key_data); |
140 return key; | 147 return key; |
141 } | 148 } |
| 149 |
| 150 |
| 151 VbPublicKey* PublicKeyRead(const char* filename) { |
| 152 VbPublicKey* key; |
| 153 uint64_t file_size; |
| 154 |
| 155 key = (VbPublicKey*)ReadFile(filename, &file_size); |
| 156 if (!key) |
| 157 return NULL; |
| 158 |
| 159 do { |
| 160 /* Sanity-check key data */ |
| 161 if (0 != VerifyPublicKeyInside(key, file_size, key)) { |
| 162 debug("PublicKeyRead() not a VbPublicKey\n"); |
| 163 break; |
| 164 } |
| 165 if (key->algorithm >= kNumAlgorithms) { |
| 166 debug("PublicKeyRead() invalid algorithm\n"); |
| 167 break; |
| 168 } |
| 169 if (key->key_version > 0xFFFF) { |
| 170 debug("PublicKeyRead() invalid version\n"); |
| 171 break; /* Currently, TPM only supports 16-bit version */ |
| 172 } |
| 173 if (RSAProcessedKeySize(key->algorithm) != key->key_size) { |
| 174 debug("PublicKeyRead() wrong key size for algorithm\n"); |
| 175 break; |
| 176 } |
| 177 |
| 178 /* Success */ |
| 179 return key; |
| 180 |
| 181 } while(0); |
| 182 |
| 183 /* Error */ |
| 184 Free(key); |
| 185 return NULL; |
| 186 } |
| 187 |
| 188 |
| 189 int PublicKeyWrite(const char* filename, const VbPublicKey* key) { |
| 190 VbPublicKey* kcopy = NULL; |
| 191 FILE* f = NULL; |
| 192 int rv = 1; |
| 193 |
| 194 do { |
| 195 f = fopen(filename, "wb"); |
| 196 if (!f) { |
| 197 debug("PublicKeyWrite() unable to open file %s\n", filename); |
| 198 break; |
| 199 } |
| 200 |
| 201 /* Copy the key, so its data is contiguous with the header */ |
| 202 kcopy = PublicKeyAlloc(key->key_size, 0, 0); |
| 203 if (!kcopy || 0 != PublicKeyCopy(kcopy, key)) |
| 204 break; |
| 205 |
| 206 if (1 != fwrite(kcopy, kcopy->key_offset + kcopy->key_size, 1, f)) |
| 207 break; |
| 208 |
| 209 /* Success */ |
| 210 rv = 0; |
| 211 |
| 212 } while(0); |
| 213 |
| 214 if (kcopy) |
| 215 Free(kcopy); |
| 216 if (f) |
| 217 fclose(f); |
| 218 |
| 219 if (0 != rv) |
| 220 unlink(filename); /* Delete any partial file */ |
| 221 |
| 222 return rv; |
| 223 } |
OLD | NEW |