aboutsummaryrefslogtreecommitdiffstats
path: root/security
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 /security
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>
Diffstat (limited to 'security')
-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 aaaa069967a..3dc3db15b5d 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];
409 int ret;
395 410
396 if (!capable(CAP_SYS_ADMIN)) 411 if (!capable(CAP_SYS_ADMIN))
397 return -EPERM; 412 return -EPERM;
398 my_get_random(hash, SHA1_DIGEST_SIZE); 413 ret = my_get_random(hash, SHA1_DIGEST_SIZE);
414 if (ret < 0)
415 return ret;
399 return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0; 416 return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0;
400} 417}
401 418
@@ -431,9 +448,8 @@ static int osap(struct tpm_buf *tb, struct osapsess *s,
431 TPM_NONCE_SIZE); 448 TPM_NONCE_SIZE);
432 memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) + 449 memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
433 TPM_NONCE_SIZE]), TPM_NONCE_SIZE); 450 TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
434 ret = TSS_rawhmac(s->secret, key, SHA1_DIGEST_SIZE, TPM_NONCE_SIZE, 451 return TSS_rawhmac(s->secret, key, SHA1_DIGEST_SIZE, TPM_NONCE_SIZE,
435 enonce, TPM_NONCE_SIZE, ononce, 0, 0); 452 enonce, TPM_NONCE_SIZE, ononce, 0, 0);
436 return ret;
437} 453}
438 454
439/* 455/*
@@ -454,7 +470,7 @@ static int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
454 *handle = LOAD32(tb->data, TPM_DATA_OFFSET); 470 *handle = LOAD32(tb->data, TPM_DATA_OFFSET);
455 memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)], 471 memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
456 TPM_NONCE_SIZE); 472 TPM_NONCE_SIZE);
457 return ret; 473 return 0;
458} 474}
459 475
460struct tpm_digests { 476struct tpm_digests {
@@ -521,20 +537,23 @@ static int tpm_seal(struct tpm_buf *tb, const uint16_t keytype,
521 /* calculate authorization HMAC value */ 537 /* calculate authorization HMAC value */
522 if (pcrinfosize == 0) { 538 if (pcrinfosize == 0) {
523 /* no pcr info specified */ 539 /* no pcr info specified */
524 TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE, 540 ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
525 sess.enonce, td->nonceodd, cont, sizeof(uint32_t), 541 sess.enonce, td->nonceodd, cont,
526 &ordinal, SHA1_DIGEST_SIZE, td->encauth, 542 sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE,
527 sizeof(uint32_t), &pcrsize, sizeof(uint32_t), 543 td->encauth, sizeof(uint32_t), &pcrsize,
528 &datsize, datalen, data, 0, 0); 544 sizeof(uint32_t), &datsize, datalen, data, 0,
545 0);
529 } else { 546 } else {
530 /* pcr info specified */ 547 /* pcr info specified */
531 TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE, 548 ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
532 sess.enonce, td->nonceodd, cont, sizeof(uint32_t), 549 sess.enonce, td->nonceodd, cont,
533 &ordinal, SHA1_DIGEST_SIZE, td->encauth, 550 sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE,
534 sizeof(uint32_t), &pcrsize, pcrinfosize, 551 td->encauth, sizeof(uint32_t), &pcrsize,
535 pcrinfo, sizeof(uint32_t), &datsize, datalen, 552 pcrinfosize, pcrinfo, sizeof(uint32_t),
536 data, 0, 0); 553 &datsize, datalen, data, 0, 0);
537 } 554 }
555 if (ret < 0)
556 return ret;
538 557
539 /* build and send the TPM request packet */ 558 /* build and send the TPM request packet */
540 INIT_BUF(tb); 559 INIT_BUF(tb);
@@ -569,8 +588,10 @@ static int tpm_seal(struct tpm_buf *tb, const uint16_t keytype,
569 0); 588 0);
570 589
571 /* copy the returned blob to caller */ 590 /* copy the returned blob to caller */
572 memcpy(blob, tb->data + TPM_DATA_OFFSET, storedsize); 591 if (!ret) {
573 *bloblen = storedsize; 592 memcpy(blob, tb->data + TPM_DATA_OFFSET, storedsize);
593 *bloblen = storedsize;
594 }
574 return ret; 595 return ret;
575} 596}
576 597
@@ -614,12 +635,16 @@ static int tpm_unseal(struct tpm_buf *tb,
614 pr_info("trusted_key: tpm_get_random failed (%d)\n", ret); 635 pr_info("trusted_key: tpm_get_random failed (%d)\n", ret);
615 return ret; 636 return ret;
616 } 637 }
617 TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE, 638 ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
618 enonce1, nonceodd, cont, sizeof(uint32_t), 639 enonce1, nonceodd, cont, sizeof(uint32_t),
619 &ordinal, bloblen, blob, 0, 0); 640 &ordinal, bloblen, blob, 0, 0);
620 TSS_authhmac(authdata2, blobauth, TPM_NONCE_SIZE, 641 if (ret < 0)
621 enonce2, nonceodd, cont, sizeof(uint32_t), 642 return ret;
622 &ordinal, bloblen, blob, 0, 0); 643 ret = TSS_authhmac(authdata2, blobauth, TPM_NONCE_SIZE,
644 enonce2, nonceodd, cont, sizeof(uint32_t),
645 &ordinal, bloblen, blob, 0, 0);
646 if (ret < 0)
647 return ret;
623 648
624 /* build and send TPM request packet */ 649 /* build and send TPM request packet */
625 INIT_BUF(tb); 650 INIT_BUF(tb);
@@ -650,10 +675,12 @@ static int tpm_unseal(struct tpm_buf *tb,
650 sizeof(uint32_t), TPM_DATA_OFFSET, 675 sizeof(uint32_t), TPM_DATA_OFFSET,
651 *datalen, TPM_DATA_OFFSET + sizeof(uint32_t), 0, 676 *datalen, TPM_DATA_OFFSET + sizeof(uint32_t), 0,
652 0); 677 0);
653 if (ret < 0) 678 if (ret < 0) {
654 pr_info("trusted_key: TSS_checkhmac2 failed (%d)\n", ret); 679 pr_info("trusted_key: TSS_checkhmac2 failed (%d)\n", ret);
680 return ret;
681 }
655 memcpy(data, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *datalen); 682 memcpy(data, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *datalen);
656 return ret; 683 return 0;
657} 684}
658 685
659/* 686/*
@@ -697,11 +724,11 @@ static int key_unseal(struct trusted_key_payload *p,
697 724
698 ret = tpm_unseal(tb, o->keyhandle, o->keyauth, p->blob, p->blob_len, 725 ret = tpm_unseal(tb, o->keyhandle, o->keyauth, p->blob, p->blob_len,
699 o->blobauth, p->key, &p->key_len); 726 o->blobauth, p->key, &p->key_len);
700 /* pull migratable flag out of sealed key */
701 p->migratable = p->key[--p->key_len];
702
703 if (ret < 0) 727 if (ret < 0)
704 pr_info("trusted_key: srkunseal failed (%d)\n", ret); 728 pr_info("trusted_key: srkunseal failed (%d)\n", ret);
729 else
730 /* pull migratable flag out of sealed key */
731 p->migratable = p->key[--p->key_len];
705 732
706 kfree(tb); 733 kfree(tb);
707 return ret; 734 return ret;
@@ -854,12 +881,11 @@ static struct trusted_key_options *trusted_options_alloc(void)
854 struct trusted_key_options *options; 881 struct trusted_key_options *options;
855 882
856 options = kzalloc(sizeof *options, GFP_KERNEL); 883 options = kzalloc(sizeof *options, GFP_KERNEL);
857 if (!options) 884 if (options) {
858 return options; 885 /* set any non-zero defaults */
859 886 options->keytype = SRK_keytype;
860 /* set any non-zero defaults */ 887 options->keyhandle = SRKHANDLE;
861 options->keytype = SRK_keytype; 888 }
862 options->keyhandle = SRKHANDLE;
863 return options; 889 return options;
864} 890}
865 891
@@ -872,9 +898,8 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
872 if (ret < 0) 898 if (ret < 0)
873 return p; 899 return p;
874 p = kzalloc(sizeof *p, GFP_KERNEL); 900 p = kzalloc(sizeof *p, GFP_KERNEL);
875 901 if (p)
876 /* migratable by default */ 902 p->migratable = 1; /* migratable by default */
877 p->migratable = 1;
878 return p; 903 return p;
879} 904}
880 905