aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2010-12-13 16:53:10 -0500
committerJames Morris <jmorris@namei.org>2010-12-15 01:44:25 -0500
commitbc5e0af0b36b6cc9de301074426c279fc9b72675 (patch)
tree116b20ec3e81f4a956ecf0fde2dfba11d43117dc
parent38ef4c2e437d11b5922723504b62824e96761459 (diff)
trusted-keys: additional TSS return code and other error handling
Previously not all TSS return codes were tested, as they were all eventually caught by the TPM. Now all returns are tested and handled immediately. This patch also fixes memory leaks in error and non-error paths. Signed-off-by: David Safford <safford@watson.ibm.com> Acked-by: Mimi Zohar <zohar@us.ibm.com> Acked-by: David Howells <dhowells@redhat.com> Acked-by: Serge E. Hallyn <serge@hallyn.com> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--security/keys/trusted_defined.c149
1 files changed, 87 insertions, 62 deletions
diff --git a/security/keys/trusted_defined.c b/security/keys/trusted_defined.c
index aaaa069967a6..3dc3db15b5d9 100644
--- a/security/keys/trusted_defined.c
+++ b/security/keys/trusted_defined.c
@@ -108,7 +108,8 @@ static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
108 goto out; 108 goto out;
109 } 109 }
110 va_end(argp); 110 va_end(argp);
111 ret = crypto_shash_final(&sdesc->shash, digest); 111 if (!ret)
112 ret = crypto_shash_final(&sdesc->shash, digest);
112out: 113out:
113 kfree(sdesc); 114 kfree(sdesc);
114 return ret; 115 return ret;
@@ -117,9 +118,9 @@ out:
117/* 118/*
118 * calculate authorization info fields to send to TPM 119 * calculate authorization info fields to send to TPM
119 */ 120 */
120static uint32_t TSS_authhmac(unsigned char *digest, const unsigned char *key, 121static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
121 const unsigned int keylen, unsigned char *h1, 122 const unsigned int keylen, unsigned char *h1,
122 unsigned char *h2, unsigned char h3, ...) 123 unsigned char *h2, unsigned char h3, ...)
123{ 124{
124 unsigned char paramdigest[SHA1_DIGEST_SIZE]; 125 unsigned char paramdigest[SHA1_DIGEST_SIZE];
125 struct sdesc *sdesc; 126 struct sdesc *sdesc;
@@ -146,15 +147,17 @@ static uint32_t TSS_authhmac(unsigned char *digest, const unsigned char *key,
146 break; 147 break;
147 data = va_arg(argp, unsigned char *); 148 data = va_arg(argp, unsigned char *);
148 ret = crypto_shash_update(&sdesc->shash, data, dlen); 149 ret = crypto_shash_update(&sdesc->shash, data, dlen);
149 if (ret < 0) 150 if (ret < 0) {
151 va_end(argp);
150 goto out; 152 goto out;
153 }
151 } 154 }
152 va_end(argp); 155 va_end(argp);
153 ret = crypto_shash_final(&sdesc->shash, paramdigest); 156 ret = crypto_shash_final(&sdesc->shash, paramdigest);
154 if (!ret) 157 if (!ret)
155 TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE, 158 ret = TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE,
156 paramdigest, TPM_NONCE_SIZE, h1, 159 paramdigest, TPM_NONCE_SIZE, h1,
157 TPM_NONCE_SIZE, h2, 1, &c, 0, 0); 160 TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
158out: 161out:
159 kfree(sdesc); 162 kfree(sdesc);
160 return ret; 163 return ret;
@@ -163,11 +166,11 @@ out:
163/* 166/*
164 * verify the AUTH1_COMMAND (Seal) result from TPM 167 * verify the AUTH1_COMMAND (Seal) result from TPM
165 */ 168 */
166static uint32_t TSS_checkhmac1(unsigned char *buffer, 169static int TSS_checkhmac1(unsigned char *buffer,
167 const uint32_t command, 170 const uint32_t command,
168 const unsigned char *ononce, 171 const unsigned char *ononce,
169 const unsigned char *key, 172 const unsigned char *key,
170 const unsigned int keylen, ...) 173 const unsigned int keylen, ...)
171{ 174{
172 uint32_t bufsize; 175 uint32_t bufsize;
173 uint16_t tag; 176 uint16_t tag;
@@ -219,18 +222,22 @@ static uint32_t TSS_checkhmac1(unsigned char *buffer,
219 break; 222 break;
220 dpos = va_arg(argp, unsigned int); 223 dpos = va_arg(argp, unsigned int);
221 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen); 224 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
222 if (ret < 0) 225 if (ret < 0) {
226 va_end(argp);
223 goto out; 227 goto out;
228 }
224 } 229 }
225 va_end(argp); 230 va_end(argp);
226 ret = crypto_shash_final(&sdesc->shash, paramdigest); 231 ret = crypto_shash_final(&sdesc->shash, paramdigest);
227 if (ret < 0) 232 if (ret < 0)
228 goto out; 233 goto out;
234
229 ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest, 235 ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest,
230 TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce, 236 TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce,
231 1, continueflag, 0, 0); 237 1, continueflag, 0, 0);
232 if (ret < 0) 238 if (ret < 0)
233 goto out; 239 goto out;
240
234 if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE)) 241 if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE))
235 ret = -EINVAL; 242 ret = -EINVAL;
236out: 243out:
@@ -241,13 +248,13 @@ out:
241/* 248/*
242 * verify the AUTH2_COMMAND (unseal) result from TPM 249 * verify the AUTH2_COMMAND (unseal) result from TPM
243 */ 250 */
244static uint32_t TSS_checkhmac2(unsigned char *buffer, 251static int TSS_checkhmac2(unsigned char *buffer,
245 const uint32_t command, 252 const uint32_t command,
246 const unsigned char *ononce, 253 const unsigned char *ononce,
247 const unsigned char *key1, 254 const unsigned char *key1,
248 const unsigned int keylen1, 255 const unsigned int keylen1,
249 const unsigned char *key2, 256 const unsigned char *key2,
250 const unsigned int keylen2, ...) 257 const unsigned int keylen2, ...)
251{ 258{
252 uint32_t bufsize; 259 uint32_t bufsize;
253 uint16_t tag; 260 uint16_t tag;
@@ -309,9 +316,12 @@ static uint32_t TSS_checkhmac2(unsigned char *buffer,
309 break; 316 break;
310 dpos = va_arg(argp, unsigned int); 317 dpos = va_arg(argp, unsigned int);
311 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen); 318 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
312 if (ret < 0) 319 if (ret < 0) {
320 va_end(argp);
313 goto out; 321 goto out;
322 }
314 } 323 }
324 va_end(argp);
315 ret = crypto_shash_final(&sdesc->shash, paramdigest); 325 ret = crypto_shash_final(&sdesc->shash, paramdigest);
316 if (ret < 0) 326 if (ret < 0)
317 goto out; 327 goto out;
@@ -319,6 +329,8 @@ static uint32_t TSS_checkhmac2(unsigned char *buffer,
319 ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE, 329 ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE,
320 paramdigest, TPM_NONCE_SIZE, enonce1, 330 paramdigest, TPM_NONCE_SIZE, enonce1,
321 TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0); 331 TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0);
332 if (ret < 0)
333 goto out;
322 if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) { 334 if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) {
323 ret = -EINVAL; 335 ret = -EINVAL;
324 goto out; 336 goto out;
@@ -326,6 +338,8 @@ static uint32_t TSS_checkhmac2(unsigned char *buffer,
326 ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE, 338 ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE,
327 paramdigest, TPM_NONCE_SIZE, enonce2, 339 paramdigest, TPM_NONCE_SIZE, enonce2,
328 TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0); 340 TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0);
341 if (ret < 0)
342 goto out;
329 if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE)) 343 if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE))
330 ret = -EINVAL; 344 ret = -EINVAL;
331out: 345out:
@@ -364,8 +378,8 @@ static int tpm_get_random(struct tpm_buf *tb, unsigned char *buf, uint32_t len)
364 store32(tb, TPM_ORD_GETRANDOM); 378 store32(tb, TPM_ORD_GETRANDOM);
365 store32(tb, len); 379 store32(tb, len);
366 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, sizeof tb->data); 380 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, sizeof tb->data);
367 memcpy(buf, tb->data + TPM_GETRANDOM_SIZE, len); 381 if (!ret)
368 382 memcpy(buf, tb->data + TPM_GETRANDOM_SIZE, len);
369 return ret; 383 return ret;
370} 384}
371 385
@@ -392,10 +406,13 @@ static int my_get_random(unsigned char *buf, int len)
392static int pcrlock(const int pcrnum) 406static int pcrlock(const int pcrnum)
393{ 407{
394 unsigned char hash[SHA1_DIGEST_SIZE]; 408 unsigned char hash[SHA1_DIGEST_SIZE];