aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2010-11-23 17:50:34 -0500
committerJames Morris <jmorris@namei.org>2010-11-28 16:55:25 -0500
commitd00a1c72f7f4661212299e6cb132dfa58030bcdb (patch)
tree2c873e461f42bbf3aea03b7b2e59cea8f941d841 /security/keys
parentc749ba912e87ccebd674ae24b97462176c63732e (diff)
keys: add new trusted key-type
Define a new kernel key-type called 'trusted'. Trusted keys are random number symmetric keys, generated and RSA-sealed by the TPM. The TPM only unseals the keys, if the boot PCRs and other criteria match. Userspace can only ever see encrypted blobs. Based on suggestions by Jason Gunthorpe, several new options have been added to support additional usages. The new options are: migratable= designates that the key may/may not ever be updated (resealed under a new key, new pcrinfo or new auth.) pcrlock=n extends the designated PCR 'n' with a random value, so that a key sealed to that PCR may not be unsealed again until after a reboot. keyhandle= specifies the sealing/unsealing key handle. keyauth= specifies the sealing/unsealing key auth. blobauth= specifies the sealed data auth. Implementation of a kernel reserved locality for trusted keys will be investigated for a possible future extension. Changelog: - Updated and added examples to Documentation/keys-trusted-encrypted.txt - Moved generic TPM constants to include/linux/tpm_command.h (David Howell's suggestion.) - trusted_defined.c: replaced kzalloc with kmalloc, added pcrlock failure error handling, added const qualifiers where appropriate. - moved to late_initcall - updated from hash to shash (suggestion by David Howells) - reduced worst stack usage (tpm_seal) from 530 to 312 bytes - moved documentation to Documentation directory (suggestion by David Howells) - all the other code cleanups suggested by David Howells - Add pcrlock CAP_SYS_ADMIN dependency (based on comment by Jason Gunthorpe) - New options: migratable, pcrlock, keyhandle, keyauth, blobauth (based on discussions with Jason Gunthorpe) - Free payload on failure to create key(reported/fixed by Roberto Sassu) - Updated Kconfig and other descriptions (based on Serge Hallyn's suggestion) - Replaced kzalloc() with kmalloc() (reported by Serge Hallyn) Signed-off-by: David Safford <safford@watson.ibm.com> Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/Makefile1
-rw-r--r--security/keys/trusted_defined.c1151
-rw-r--r--security/keys/trusted_defined.h134
3 files changed, 1286 insertions, 0 deletions
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 74d5447d7df7..fcb107020b4a 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -13,6 +13,7 @@ obj-y := \
13 request_key_auth.o \ 13 request_key_auth.o \
14 user_defined.o 14 user_defined.o
15 15
16obj-$(CONFIG_TRUSTED_KEYS) += trusted_defined.o
16obj-$(CONFIG_KEYS_COMPAT) += compat.o 17obj-$(CONFIG_KEYS_COMPAT) += compat.o
17obj-$(CONFIG_PROC_FS) += proc.o 18obj-$(CONFIG_PROC_FS) += proc.o
18obj-$(CONFIG_SYSCTL) += sysctl.o 19obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/trusted_defined.c b/security/keys/trusted_defined.c
new file mode 100644
index 000000000000..1bec72e7596d
--- /dev/null
+++ b/security/keys/trusted_defined.c
@@ -0,0 +1,1151 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 *
4 * Author:
5 * David Safford <safford@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 * See Documentation/keys-trusted-encrypted.txt
12 */
13
14#include <linux/uaccess.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/parser.h>
19#include <linux/string.h>
20#include <keys/user-type.h>
21#include <keys/trusted-type.h>
22#include <linux/key-type.h>
23#include <linux/rcupdate.h>
24#include <linux/crypto.h>
25#include <crypto/hash.h>
26#include <crypto/sha.h>
27#include <linux/capability.h>
28#include <linux/tpm.h>
29#include <linux/tpm_command.h>
30
31#include "trusted_defined.h"
32
33static const char hmac_alg[] = "hmac(sha1)";
34static const char hash_alg[] = "sha1";
35
36struct sdesc {
37 struct shash_desc shash;
38 char ctx[];
39};
40
41static struct crypto_shash *hashalg;
42static struct crypto_shash *hmacalg;
43
44static struct sdesc *init_sdesc(struct crypto_shash *alg)
45{
46 struct sdesc *sdesc;
47 int size;
48
49 size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
50 sdesc = kmalloc(size, GFP_KERNEL);
51 if (!sdesc)
52 return ERR_PTR(-ENOMEM);
53 sdesc->shash.tfm = alg;
54 sdesc->shash.flags = 0x0;
55 return sdesc;
56}
57
58static int TSS_sha1(const unsigned char *data, const unsigned int datalen,
59 unsigned char *digest)
60{
61 struct sdesc *sdesc;
62 int ret;
63
64 sdesc = init_sdesc(hashalg);
65 if (IS_ERR(sdesc)) {
66 pr_info("trusted_key: can't alloc %s\n", hash_alg);
67 return PTR_ERR(sdesc);
68 }
69
70 ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
71 kfree(sdesc);
72 return ret;
73}
74
75static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
76 const unsigned int keylen, ...)
77{
78 struct sdesc *sdesc;
79 va_list argp;
80 unsigned int dlen;
81 unsigned char *data;
82 int ret;
83
84 sdesc = init_sdesc(hmacalg);
85 if (IS_ERR(sdesc)) {
86 pr_info("trusted_key: can't alloc %s\n", hmac_alg);
87 return PTR_ERR(sdesc);
88 }
89
90 ret = crypto_shash_setkey(hmacalg, key, keylen);
91 if (ret < 0)
92 goto out;
93 ret = crypto_shash_init(&sdesc->shash);
94 if (ret < 0)
95 goto out;
96
97 va_start(argp, keylen);
98 for (;;) {
99 dlen = va_arg(argp, unsigned int);
100 if (dlen == 0)
101 break;
102 data = va_arg(argp, unsigned char *);
103 if (data == NULL)
104 return -EINVAL;
105 ret = crypto_shash_update(&sdesc->shash, data, dlen);
106 if (ret < 0)
107 goto out;
108 }
109 va_end(argp);
110 ret = crypto_shash_final(&sdesc->shash, digest);
111out:
112 kfree(sdesc);
113 return ret;
114}
115
116/*
117 * calculate authorization info fields to send to TPM
118 */
119static uint32_t TSS_authhmac(unsigned char *digest, const unsigned char *key,
120 const unsigned int keylen, unsigned char *h1,
121 unsigned char *h2, unsigned char h3, ...)
122{
123 unsigned char paramdigest[SHA1_DIGEST_SIZE];
124 struct sdesc *sdesc;
125 unsigned int dlen;
126 unsigned char *data;
127 unsigned char c;
128 int ret;
129 va_list argp;
130
131 sdesc = init_sdesc(hashalg);
132 if (IS_ERR(sdesc)) {
133 pr_info("trusted_key: can't alloc %s\n", hash_alg);
134 return PTR_ERR(sdesc);
135 }
136
137 c = h3;
138 ret = crypto_shash_init(&sdesc->shash);
139 if (ret < 0)
140 goto out;
141 va_start(argp, h3);
142 for (;;) {
143 dlen = va_arg(argp, unsigned int);
144 if (dlen == 0)
145 break;
146 data = va_arg(argp, unsigned char *);
147 ret = crypto_shash_update(&sdesc->shash, data, dlen);
148 if (ret < 0)
149 goto out;
150 }
151 va_end(argp);
152 ret = crypto_shash_final(&sdesc->shash, paramdigest);
153 if (!ret)
154 TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE,
155 paramdigest, TPM_NONCE_SIZE, h1,
156 TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
157out:
158 kfree(sdesc);
159 return ret;
160}
161
162/*
163 * verify the AUTH1_COMMAND (Seal) result from TPM
164 */
165static uint32_t TSS_checkhmac1(unsigned char *buffer,
166 const uint32_t command,
167 const unsigned char *ononce,
168 const unsigned char *key,
169 const unsigned int keylen, ...)
170{
171 uint32_t bufsize;
172 uint16_t tag;
173 uint32_t ordinal;
174 uint32_t result;
175 unsigned char *enonce;
176 unsigned char *continueflag;
177 unsigned char *authdata;
178 unsigned char testhmac[SHA1_DIGEST_SIZE];
179 unsigned char paramdigest[SHA1_DIGEST_SIZE];
180 struct sdesc *sdesc;
181 unsigned int dlen;
182 unsigned int dpos;
183 va_list argp;
184 int ret;
185
186 bufsize = LOAD32(buffer, TPM_SIZE_OFFSET);
187 tag = LOAD16(buffer, 0);
188 ordinal = command;
189 result = LOAD32N(buffer, TPM_RETURN_OFFSET);
190 if (tag == TPM_TAG_RSP_COMMAND)
191 return 0;
192 if (tag != TPM_TAG_RSP_AUTH1_COMMAND)
193 return -EINVAL;
194 authdata = buffer + bufsize - SHA1_DIGEST_SIZE;
195 continueflag = authdata - 1;
196 enonce = continueflag - TPM_NONCE_SIZE;
197
198 sdesc = init_sdesc(hashalg);
199 if (IS_ERR(sdesc)) {
200 pr_info("trusted_key: can't alloc %s\n", hash_alg);
201 return PTR_ERR(sdesc);
202 }
203 ret = crypto_shash_init(&sdesc->shash);
204 if (ret < 0)
205 goto out;
206 ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
207 sizeof result);
208 if (ret < 0)
209 goto out;
210 ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
211 sizeof ordinal);
212 if (ret < 0)
213 goto out;
214 va_start(argp, keylen);
215 for (;;) {
216 dlen = va_arg(argp, unsigned int);
217 if (dlen == 0)
218 break;
219 dpos = va_arg(argp, unsigned int);
220 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
221 if (ret < 0)
222 goto out;
223 }
224 va_end(argp);
225 ret = crypto_shash_final(&sdesc->shash, paramdigest);
226 if (ret < 0)
227 goto out;
228 ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest,
229 TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce,
230 1, continueflag, 0, 0);
231 if (ret < 0)
232 goto out;
233 if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE))
234 ret = -EINVAL;
235out:
236 kfree(sdesc);
237 return ret;
238}
239
240/*
241 * verify the AUTH2_COMMAND (unseal) result from TPM
242 */
243static uint32_t TSS_checkhmac2(unsigned char *buffer,
244 const uint32_t command,
245 const unsigned char *ononce,
246 const unsigned char *key1,
247 const unsigned int keylen1,
248 const unsigned char *key2,
249 const unsigned int keylen2, ...)
250{
251 uint32_t bufsize;
252 uint16_t tag;
253 uint32_t ordinal;
254 uint32_t result;
255 unsigned char *enonce1;
256 unsigned char *continueflag1;
257 unsigned char *authdata1;
258 unsigned char *enonce2;
259 unsigned char *continueflag2;
260 unsigned char *authdata2;
261 unsigned char testhmac1[SHA1_DIGEST_SIZE];
262 unsigned char testhmac2[SHA1_DIGEST_SIZE];
263 unsigned char paramdigest[SHA1_DIGEST_SIZE];
264 struct sdesc *sdesc;
265 unsigned int dlen;
266 unsigned int dpos;
267 va_list argp;
268 int ret;
269
270 bufsize = LOAD32(buffer, TPM_SIZE_OFFSET);
271 tag = LOAD16(buffer, 0);
272 ordinal = command;
273 result = LOAD32N(buffer, TPM_RETURN_OFFSET);
274
275 if (tag == TPM_TAG_RSP_COMMAND)
276 return 0;
277 if (tag != TPM_TAG_RSP_AUTH2_COMMAND)
278 return -EINVAL;
279 authdata1 = buffer + bufsize - (SHA1_DIGEST_SIZE + 1
280 + SHA1_DIGEST_SIZE + SHA1_DIGEST_SIZE);
281 authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE);
282 continueflag1 = authdata1 - 1;
283 continueflag2 = authdata2 - 1;
284 enonce1 = continueflag1 - TPM_NONCE_SIZE;
285 enonce2 = continueflag2 - TPM_NONCE_SIZE;
286
287 sdesc = init_sdesc(hashalg);
288 if (IS_ERR(sdesc)) {
289 pr_info("trusted_key: can't alloc %s\n", hash_alg);
290 return PTR_ERR(sdesc);
291 }
292 ret = crypto_shash_init(&sdesc->shash);
293 if (ret < 0)
294 goto out;
295 ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
296 sizeof result);
297 if (ret < 0)
298 goto out;
299 ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
300 sizeof ordinal);
301 if (ret < 0)
302 goto out;
303
304 va_start(argp, keylen2);
305 for (;;) {
306 dlen = va_arg(argp, unsigned int);
307 if (dlen == 0)
308 break;
309 dpos = va_arg(argp, unsigned int);
310 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
311 if (ret < 0)
312 goto out;
313 }
314 ret = crypto_shash_final(&sdesc->shash, paramdigest);
315 if (ret < 0)
316 goto out;
317
318 ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE,
319 paramdigest, TPM_NONCE_SIZE, enonce1,
320 TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0);
321 if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) {
322 ret = -EINVAL;
323 goto out;
324 }
325 ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE,
326 paramdigest, TPM_NONCE_SIZE, enonce2,
327 TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0);
328 if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE))
329 ret = -EINVAL;
330out:
331 kfree(sdesc);
332 return ret;
333}
334
335/*
336 * For key specific tpm requests, we will generate and send our
337 * own TPM command packets using the drivers send function.
338 */
339static int trusted_tpm_send(const u32 chip_num, unsigned char *cmd,
340 size_t buflen)
341{
342 int rc;
343
344 dump_tpm_buf(cmd);
345 rc = tpm_send(chip_num, cmd, buflen);
346 dump_tpm_buf(cmd);
347 if (rc > 0)
348 /* Can't return positive return codes values to keyctl */
349 rc = -EPERM;
350 return rc;
351}
352
353/*
354 * get a random value from TPM
355 */
356static int tpm_get_random(struct tpm_buf *tb, unsigned char *buf, uint32_t len)
357{
358 int ret;
359
360 INIT_BUF(tb);
361 store16(tb, TPM_TAG_RQU_COMMAND);
362 store32(tb, TPM_GETRANDOM_SIZE);
363 store32(tb, TPM_ORD_GETRANDOM);
364 store32(tb, len);
365 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, sizeof tb->data);
366 memcpy(buf, tb->data + TPM_GETRANDOM_SIZE, len);
367
368 return ret;
369}
370
371static int my_get_random(unsigned char *buf, int len)
372{
373 struct tpm_buf *tb;
374 int ret;
375
376 tb = kzalloc(sizeof *tb, GFP_KERNEL);
377 if (!tb)
378 return -ENOMEM;
379 ret = tpm_get_random(tb, buf, len);
380
381 kfree(tb);
382 return ret;
383}
384
385/*
386 * Lock a trusted key, by extending a selected PCR.
387 *
388 * Prevents a trusted key that is sealed to PCRs from being accessed.
389 * This uses the tpm driver's extend function.
390 */
391static int pcrlock(const int pcrnum)
392{
393 unsigned char hash[SHA1_DIGEST_SIZE];
394
395 if (!capable(CAP_SYS_ADMIN))
396 return -EPERM;
397 my_get_random(hash, SHA1_DIGEST_SIZE);
398 return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0;
399}
400
401/*
402 * Create an object specific authorisation protocol (OSAP) session
403 */
404static int osap(struct tpm_buf *tb, struct osapsess *s,
405 const unsigned char *key, const uint16_t type,
406 const uint32_t handle)
407{
408 unsigned char enonce[TPM_NONCE_SIZE];
409 unsigned char ononce[TPM_NONCE_SIZE];
410 int ret;
411
412 ret = tpm_get_random(tb, ononce, TPM_NONCE_SIZE);
413 if (ret < 0)
414 return ret;
415
416 INIT_BUF(tb);
417 store16(tb, TPM_TAG_RQU_COMMAND);
418 store32(tb, TPM_OSAP_SIZE);
419 store32(tb, TPM_ORD_OSAP);
420 store16(tb, type);
421 store32(tb, handle);
422 storebytes(tb, ononce, TPM_NONCE_SIZE);
423
424 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
425 if (ret < 0)
426 return ret;
427
428 s->handle = LOAD32(tb->data, TPM_DATA_OFFSET);
429 memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
430 TPM_NONCE_SIZE);
431 memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
432 TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
433 ret = TSS_rawhmac(s->secret, key, SHA1_DIGEST_SIZE, TPM_NONCE_SIZE,
434 enonce, TPM_NONCE_SIZE, ononce, 0, 0);
435 return ret;
436}
437
438/*
439 * Create an object independent authorisation protocol (oiap) session
440 */
441static int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
442{
443 int ret;
444
445 INIT_BUF(tb);
446 store16(tb, TPM_TAG_RQU_COMMAND);
447 store32(tb, TPM_OIAP_SIZE);
448 store32(tb, TPM_ORD_OIAP);
449 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
450 if (ret < 0)
451 return ret;
452
453 *handle = LOAD32(tb->data, TPM_DATA_OFFSET);
454 memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
455 TPM_NONCE_SIZE);
456 return ret;
457}
458
459struct tpm_digests {
460 unsigned char encauth[SHA1_DIGEST_SIZE];
461 unsigned char pubauth[SHA1_DIGEST_SIZE];
462 unsigned char xorwork[SHA1_DIGEST_SIZE * 2];
463 unsigned char xorhash[SHA1_DIGEST_SIZE];
464 unsigned char nonceodd[TPM_NONCE_SIZE];
465};
466
467/*
468 * Have the TPM seal(encrypt) the trusted key, possibly based on
469 * Platform Configuration Registers (PCRs). AUTH1 for sealing key.
470 */
471static int tpm_seal(struct tpm_buf *tb, const uint16_t keytype,
472 const uint32_t keyhandle, const unsigned char *keyauth,
473 const unsigned char *data, const uint32_t datalen,
474 unsigned char *blob, uint32_t *bloblen,
475 const unsigned char *blobauth,
476 const unsigned char *pcrinfo, const uint32_t pcrinfosize)
477{
478 struct osapsess sess;
479 struct tpm_digests *td;
480 unsigned char cont;
481 uint32_t ordinal;
482 uint32_t pcrsize;
483 uint32_t datsize;
484 int sealinfosize;
485 int encdatasize;
486 int storedsize;
487 int ret;
488 int i;
489
490 /* alloc some work space for all the hashes */
491 td = kmalloc(sizeof *td, GFP_KERNEL);
492 if (!td)
493 return -ENOMEM;
494
495 /* get session for sealing key */
496 ret = osap(tb, &sess, keyauth, keytype, keyhandle);
497 if (ret < 0)
498 return ret;
499 dump_sess(&sess);
500
501 /* calculate encrypted authorization value */
502 memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
503 memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
504 ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
505 if (ret < 0)
506 return ret;
507
508 ret = tpm_get_random(tb, td->nonceodd, TPM_NONCE_SIZE);
509 if (ret < 0)
510 return ret;
511 ordinal = htonl(TPM_ORD_SEAL);
512 datsize = htonl(datalen);
513 pcrsize = htonl(pcrinfosize);
514 cont = 0;
515
516 /* encrypt data authorization key */
517 for (i = 0; i < SHA1_DIGEST_SIZE; ++i)
518 td->encauth[i] = td->xorhash[i] ^ blobauth[i];
519
520 /* calculate authorization HMAC value */
521 if (pcrinfosize == 0) {
522 /* no pcr info specified */
523 TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
524 sess.enonce, td->nonceodd, cont, sizeof(uint32_t),
525 &ordinal, SHA1_DIGEST_SIZE, td->encauth,
526 sizeof(uint32_t), &pcrsize, sizeof(uint32_t),
527 &datsize, datalen, data, 0, 0);
528 } else {
529 /* pcr info specified */
530 TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
531 sess.enonce, td->nonceodd, cont, sizeof(uint32_t),
532 &ordinal, SHA1_DIGEST_SIZE, td->encauth,
533 sizeof(uint32_t), &pcrsize, pcrinfosize,
534 pcrinfo, sizeof(uint32_t), &datsize, datalen,
535 data, 0, 0);
536 }
537
538 /* build and send the TPM request packet */
539 INIT_BUF(tb);
540 store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
541 store32(tb, TPM_SEAL_SIZE + pcrinfosize + datalen);
542 store32(tb, TPM_ORD_SEAL);
543 store32(tb, keyhandle);
544 storebytes(tb, td->encauth, SHA1_DIGEST_SIZE);
545 store32(tb, pcrinfosize);
546 storebytes(tb, pcrinfo, pcrinfosize);
547 store32(tb, datalen);
548 storebytes(tb, data, datalen);
549 store32(tb, sess.handle);
550 storebytes(tb, td->nonceodd, TPM_NONCE_SIZE);
551 store8(tb, cont);
552 storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE);
553
554 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
555 if (ret < 0)
556 return ret;
557
558 /* calculate the size of the returned Blob */
559 sealinfosize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t));
560 encdatasize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t) +
561 sizeof(uint32_t) + sealinfosize);
562 storedsize = sizeof(uint32_t) + sizeof(uint32_t) + sealinfosize +
563 sizeof(uint32_t) + encdatasize;
564
565 /* check the HMAC in the response */
566 ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd, sess.secret,
567 SHA1_DIGEST_SIZE, storedsize, TPM_DATA_OFFSET, 0,
568 0);
569
570 /* copy the returned blob to caller */
571 memcpy(blob, tb->data + TPM_DATA_OFFSET, storedsize);
572 *bloblen = storedsize;
573 return ret;
574}
575
576/*
577 * use the AUTH2_COMMAND form of unseal, to authorize both key and blob
578 */
579static int tpm_unseal(struct tpm_buf *tb,
580 const uint32_t keyhandle, const unsigned char *keyauth,
581 const unsigned char *blob, const int bloblen,
582 const unsigned char *blobauth,
583 unsigned char *data, unsigned int *datalen)
584{
585 unsigned char nonceodd[TPM_NONCE_SIZE];
586 unsigned char enonce1[TPM_NONCE_SIZE];
587 unsigned char enonce2[TPM_NONCE_SIZE];
588 unsigned char authdata1[SHA1_DIGEST_SIZE];
589 unsigned char authdata2[SHA1_DIGEST_SIZE];
590 uint32_t authhandle1 = 0;
591 uint32_t authhandle2 = 0;
592 unsigned char cont = 0;
593 uint32_t ordinal;
594 uint32_t keyhndl;
595 int ret;
596
597 /* sessions for unsealing key and data */
598 ret = oiap(tb, &authhandle1, enonce1);
599 if (ret < 0) {
600 pr_info("trusted_key: oiap failed (%d)\n", ret);
601 return ret;
602 }
603 ret = oiap(tb, &authhandle2, enonce2);
604 if (ret < 0) {
605 pr_info("trusted_key: oiap failed (%d)\n", ret);
606 return ret;
607 }
608
609 ordinal = htonl(TPM_ORD_UNSEAL);
610 keyhndl = htonl(SRKHANDLE);
611 ret = tpm_get_random(tb, nonceodd, TPM_NONCE_SIZE);
612 if (ret < 0) {
613 pr_info("trusted_key: tpm_get_random failed (%d)\n", ret);
614 return ret;
615 }
616 TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
617 enonce1, nonceodd, cont, sizeof(uint32_t),
618 &ordinal, bloblen, blob, 0, 0);
619 TSS_authhmac(authdata2, blobauth, TPM_NONCE_SIZE,
620 enonce2, nonceodd, cont, sizeof(uint32_t),
621 &ordinal, bloblen, blob, 0, 0);
622
623 /* build and send TPM request packet */
624 INIT_BUF(tb);
625 store16(tb, TPM_TAG_RQU_AUTH2_COMMAND);
626 store32(tb, TPM_UNSEAL_SIZE + bloblen);
627 store32(tb, TPM_ORD_UNSEAL);
628 store32(tb, keyhandle);
629 storebytes(tb, blob, bloblen);
630 store32(tb, authhandle1);
631 storebytes(tb, nonceodd, TPM_NONCE_SIZE);
632 store8(tb, cont);
633 storebytes(tb, authdata1, SHA1_DIGEST_SIZE);
634 store32(tb, authhandle2);
635 storebytes(tb, nonceodd, TPM_NONCE_SIZE);
636 store8(tb, cont);
637 storebytes(tb, authdata2, SHA1_DIGEST_SIZE);
638
639 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
640 if (ret < 0) {
641 pr_info("trusted_key: authhmac failed (%d)\n", ret);
642 return ret;
643 }
644
645 *datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
646 ret = TSS_checkhmac2(tb->data, ordinal, nonceodd,
647 keyauth, SHA1_DIGEST_SIZE,
648 blobauth, SHA1_DIGEST_SIZE,
649 sizeof(uint32_t), TPM_DATA_OFFSET,
650 *datalen, TPM_DATA_OFFSET + sizeof(uint32_t), 0,
651 0);
652 if (ret < 0)
653 pr_info("trusted_key: TSS_checkhmac2 failed (%d)\n", ret);
654 memcpy(data, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *datalen);
655 return ret;
656}
657
658/*
659 * Have the TPM seal(encrypt) the symmetric key
660 */
661static int key_seal(struct trusted_key_payload *p,
662 struct trusted_key_options *o)
663{
664 struct tpm_buf *tb;
665 int ret;
666
667 tb = kzalloc(sizeof *tb, GFP_KERNEL);
668 if (!tb)
669 return -ENOMEM;
670
671 /* include migratable flag at end of sealed key */
672 p->key[p->key_len] = p->migratable;
673
674 ret = tpm_seal(tb, o->keytype, o->keyhandle, o->keyauth,
675 p->key, p->key_len + 1, p->blob, &p->blob_len,
676 o->blobauth, o->pcrinfo, o->pcrinfo_len);
677 if (ret < 0)
678 pr_info("trusted_key: srkseal failed (%d)\n", ret);
679
680 kfree(tb);
681 return ret;
682}
683
684/*
685 * Have the TPM unseal(decrypt) the symmetric key
686 */
687static int key_unseal(struct trusted_key_payload *p,
688 struct trusted_key_options *o)
689{
690 struct tpm_buf *tb;
691 int ret;
692
693 tb = kzalloc(sizeof *tb, GFP_KERNEL);
694 if (!tb)
695 return -ENOMEM;
696
697 ret = tpm_unseal(tb, o->keyhandle, o->keyauth, p->blob, p->blob_len,
698 o->blobauth, p->key, &p->key_len);
699 /* pull migratable flag out of sealed key */
700 p->migratable = p->key[--p->key_len];
701
702 if (ret < 0)
703 pr_info("trusted_key: srkunseal failed (%d)\n", ret);
704
705 kfree(tb);
706 return ret;
707}
708
709enum {
710 Opt_err = -1,
711 Opt_new, Opt_load, Opt_update,
712 Opt_keyhandle, Opt_keyauth, Opt_blobauth,
713 Opt_pcrinfo, Opt_pcrlock, Opt_migratable
714};
715
716static const match_table_t key_tokens = {
717 {Opt_new, "new"},
718 {Opt_load, "load"},
719 {Opt_update, "update"},
720 {Opt_keyhandle, "keyhandle=%s"},
721 {Opt_keyauth, "keyauth=%s"},
722 {Opt_blobauth, "blobauth=%s"},
723 {Opt_pcrinfo, "pcrinfo=%s"},
724 {Opt_pcrlock, "pcrlock=%s"},
725 {Opt_migratable, "migratable=%s"},
726 {Opt_err, NULL}
727};
728
729/* can have zero or more token= options */
730static int getoptions(char *c, struct trusted_key_payload *pay,
731 struct trusted_key_options *opt)
732{
733 substring_t args[MAX_OPT_ARGS];
734 char *p = c;
735 int token;
736 int res;
737 unsigned long handle;
738 unsigned long lock;
739
740 while ((p = strsep(&c, " \t"))) {
741 if (*p == '\0' || *p == ' ' || *p == '\t')
742 continue;
743 token = match_token(p, key_tokens, args);
744
745 switch (token) {
746 case Opt_pcrinfo:
747 opt->pcrinfo_len = strlen(args[0].from) / 2;
748 if (opt->pcrinfo_len > MAX_PCRINFO_SIZE)
749 return -EINVAL;
750 hex2bin(opt->pcrinfo, args[0].from, opt->pcrinfo_len);
751 break;
752 case Opt_keyhandle:
753 res = strict_strtoul(args[0].from, 16, &handle);
754 if (res < 0)
755 return -EINVAL;
756 opt->keytype = SEAL_keytype;
757 opt->keyhandle = handle;
758 break;
759 case Opt_keyauth:
760 if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE)
761 return -EINVAL;
762 hex2bin(opt->keyauth, args[0].from, SHA1_DIGEST_SIZE);
763 break;
764 case Opt_blobauth:
765 if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE)
766 return -EINVAL;
767 hex2bin(opt->blobauth, args[0].from, SHA1_DIGEST_SIZE);
768 break;
769 case Opt_migratable:
770 if (*args[0].from == '0')
771 pay->migratable = 0;
772 else
773 return -EINVAL;
774 break;
775 case Opt_pcrlock:
776 res = strict_strtoul(args[0].from, 10, &lock);
777 if (res < 0)
778 return -EINVAL;
779 opt->pcrlock = lock;
780 break;
781 default:
782 return -EINVAL;
783 }
784 }
785 return 0;
786}
787
788/*
789 * datablob_parse - parse the keyctl data and fill in the
790 * payload and options structures
791 *
792 * On success returns 0, otherwise -EINVAL.
793 */
794static int datablob_parse(char *datablob, struct trusted_key_payload *p,
795 struct trusted_key_options *o)
796{
797 substring_t args[MAX_OPT_ARGS];
798 long keylen;
799 int ret = -EINVAL;
800 int key_cmd;
801 char *c;
802
803 /* main command */
804 c = strsep(&datablob, " \t");
805 if (!c)
806 return -EINVAL;
807 key_cmd = match_token(c, key_tokens, args);
808 switch (key_cmd) {
809 case Opt_new:
810 /* first argument is key size */
811 c = strsep(&datablob, " \t");
812 if (!c)
813 return -EINVAL;
814 ret = strict_strtol(c, 10, &keylen);
815 if (ret < 0 || keylen < MIN_KEY_SIZE || keylen > MAX_KEY_SIZE)
816 return -EINVAL;
817 p->key_len = keylen;
818 ret = getoptions(datablob, p, o);
819 if (ret < 0)
820 return ret;
821 ret = Opt_new;
822 break;
823 case Opt_load:
824 /* first argument is sealed blob */
825 c = strsep(&datablob, " \t");
826 if (!c)
827 return -EINVAL;
828 p->blob_len = strlen(c) / 2;
829 if (p->blob_len > MAX_BLOB_SIZE)
830 return -EINVAL;
831 hex2bin(p->blob, c, p->blob_len);
832 ret = getoptions(datablob, p, o);
833 if (ret < 0)
834 return ret;
835 ret = Opt_load;
836 break;
837 case Opt_update:
838 /* all arguments are options */
839 ret = getoptions(datablob, p, o);
840 if (ret < 0)
841 return ret;
842 ret = Opt_update;
843 break;
844 case Opt_err:
845 return -EINVAL;
846 break;
847 }
848 return ret;
849}
850
851static struct trusted_key_options *trusted_options_alloc(void)
852{
853 struct trusted_key_options *options;
854
855 options = kzalloc(sizeof *options, GFP_KERNEL);
856 if (!options)
857 return options;
858
859 /* set any non-zero defaults */
860 options->keytype = SRK_keytype;
861 options->keyhandle = SRKHANDLE;
862 return options;
863}
864
865static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
866{
867 struct trusted_key_payload *p = NULL;
868 int ret;
869
870 ret = key_payload_reserve(key, sizeof *p);
871 if (ret < 0)
872 return p;
873 p = kzalloc(sizeof *p, GFP_KERNEL);
874
875 /* migratable by default */
876 p->migratable = 1;
877 return p;
878}
879
880/*
881 * trusted_instantiate - create a new trusted key
882 *
883 * Unseal an existing trusted blob or, for a new key, get a
884 * random key, then seal and create a trusted key-type key,
885 * adding it to the specified keyring.
886 *
887 * On success, return 0. Otherwise return errno.
888 */
889static int trusted_instantiate(struct key *key, const void *data,
890 const size_t datalen)
891{
892 struct trusted_key_payload *payload = NULL;
893 struct trusted_key_options *options = NULL;
894 char *datablob;
895 int ret = 0;
896 int key_cmd;
897
898 if (datalen <= 0 || datalen > 32767 || !data)
899 return -EINVAL;
900
901 datablob = kmalloc(datalen + 1, GFP_KERNEL);
902 if (!datablob)
903 return -ENOMEM;
904 memcpy(datablob, data, datalen);
905 datablob[datalen] = '\0';
906
907 options = trusted_options_alloc();
908 if (!options) {
909 ret = -ENOMEM;
910 goto out;
911 }
912 payload = trusted_payload_alloc(key);
913 if (!payload) {
914 ret = -ENOMEM;
915 goto out;
916 }
917
918 key_cmd = datablob_parse(datablob, payload, options);
919 if (key_cmd < 0) {
920 ret = key_cmd;
921 goto out;
922 }
923
924 dump_payload(payload);
925 dump_options(options);
926
927 switch (key_cmd) {
928 case Opt_load:
929 ret = key_unseal(payload, options);
930 dump_payload(payload);
931 dump_options(options);
932 if (ret < 0)
933 pr_info("trusted_key: key_unseal failed (%d)\n", ret);
934 break;
935 case Opt_new:
936 ret = my_get_random(payload->key, payload->key_len);
937 if (ret < 0) {
938 pr_info("trusted_key: key_create failed (%d)\n", ret);
939 goto out;
940 }
941 ret = key_seal(payload, options);
942 if (ret < 0)
943 pr_info("trusted_key: key_seal failed (%d)\n", ret);
944 break;
945 default:
946 ret = -EINVAL;
947 goto out;
948 }
949 if (!ret && options->pcrlock)
950 ret = pcrlock(options->pcrlock);
951out:
952 kfree(datablob);
953 kfree(options);
954 if (!ret)
955 rcu_assign_pointer(key->payload.data, payload);
956 else
957 kfree(payload);
958 return ret;
959}
960
961static void trusted_rcu_free(struct rcu_head *rcu)
962{
963 struct trusted_key_payload *p;
964
965 p = container_of(rcu, struct trusted_key_payload, rcu);
966 memset(p->key, 0, p->key_len);
967 kfree(p);
968}
969
970/*
971 * trusted_update - reseal an existing key with new PCR values
972 */
973static int trusted_update(struct key *key, const void *data,
974 const size_t datalen)
975{
976 struct trusted_key_payload *p = key->payload.data;
977 struct trusted_key_payload *new_p;
978 struct trusted_key_options *new_o;
979 char *datablob;
980 int ret = 0;
981
982 if (!p->migratable)
983 return -EPERM;
984 if (datalen <= 0 || datalen > 32767 || !data)
985 return -EINVAL;
986
987 datablob = kmalloc(datalen + 1, GFP_KERNEL);
988 if (!datablob)
989 return -ENOMEM;
990 new_o = trusted_options_alloc();
991 if (!new_o) {
992 ret = -ENOMEM;
993 goto out;
994 }
995 new_p = trusted_payload_alloc(key);
996 if (!new_p) {
997 ret = -ENOMEM;
998 goto out;
999 }
1000
1001 memcpy(datablob, data, datalen);
1002 datablob[datalen] = '\0';
1003 ret = datablob_parse(datablob, new_p, new_o);
1004 if (ret != Opt_update) {
1005 ret = -EINVAL;
1006 goto out;
1007 }
1008 /* copy old key values, and reseal with new pcrs */
1009 new_p->migratable = p->migratable;
1010 new_p->key_len = p->key_len;
1011 memcpy(new_p->key, p->key, p->key_len);
1012 dump_payload(p);
1013 dump_payload(new_p);
1014
1015 ret = key_seal(new_p, new_o);
1016 if (ret < 0) {
1017 pr_info("trusted_key: key_seal failed (%d)\n", ret);
1018 kfree(new_p);
1019 goto out;
1020 }
1021 if (new_o->pcrlock) {
1022 ret = pcrlock(new_o->pcrlock);
1023 if (ret < 0) {
1024 pr_info("trusted_key: pcrlock failed (%d)\n", ret);
1025 kfree(new_p);
1026 goto out;
1027 }
1028 }
1029 rcu_assign_pointer(key->payload.data, new_p);
1030 call_rcu(&p->rcu, trusted_rcu_free);
1031out:
1032 kfree(datablob);
1033 kfree(new_o);
1034 return ret;
1035}
1036
1037/*
1038 * trusted_read - copy the sealed blob data to userspace in hex.
1039 * On success, return to userspace the trusted key datablob size.
1040 */
1041static long trusted_read(const struct key *key, char __user *buffer,
1042 size_t buflen)
1043{
1044 struct trusted_key_payload *p;
1045 char *ascii_buf;
1046 char *bufp;
1047 int i;
1048
1049 p = rcu_dereference_protected(key->payload.data,
1050 rwsem_is_locked(&((struct key *)key)->sem));
1051 if (!p)
1052 return -EINVAL;
1053 if (!buffer || buflen <= 0)
1054 return 2 * p->blob_len;
1055 ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
1056 if (!ascii_buf)
1057 return -ENOMEM;
1058
1059 bufp = ascii_buf;
1060 for (i = 0; i < p->blob_len; i++)
1061 bufp = pack_hex_byte(bufp, p->blob[i]);
1062 if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) {
1063 kfree(ascii_buf);
1064 return -EFAULT;
1065 }
1066 kfree(ascii_buf);
1067 return 2 * p->blob_len;
1068}
1069
1070/*
1071 * trusted_destroy - before freeing the key, clear the decrypted data
1072 */
1073static void trusted_destroy(struct key *key)
1074{
1075 struct trusted_key_payload *p = key->payload.data;
1076
1077 if (!p)
1078 return;
1079 memset(p->key, 0, p->key_len);
1080 kfree(key->payload.data);
1081}
1082
1083struct key_type key_type_trusted = {
1084 .name = "trusted",
1085 .instantiate = trusted_instantiate,
1086 .update = trusted_update,
1087 .match = user_match,
1088 .destroy = trusted_destroy,
1089 .describe = user_describe,
1090 .read = trusted_read,
1091};
1092
1093EXPORT_SYMBOL_GPL(key_type_trusted);
1094
1095static void trusted_shash_release(void)
1096{
1097 if (hashalg)
1098 crypto_free_shash(hashalg);
1099 if (hmacalg)
1100 crypto_free_shash(hmacalg);
1101}
1102
1103static int __init trusted_shash_alloc(void)
1104{
1105 int ret;
1106
1107 hmacalg = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC);
1108 if (IS_ERR(hmacalg)) {
1109 pr_info("trusted_key: could not allocate crypto %s\n",
1110 hmac_alg);
1111 return PTR_ERR(hmacalg);
1112 }
1113
1114 hashalg = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC);
1115 if (IS_ERR(hashalg)) {
1116 pr_info("trusted_key: could not allocate crypto %s\n",
1117 hash_alg);
1118 ret = PTR_ERR(hashalg);
1119 goto hashalg_fail;
1120 }
1121
1122 return 0;
1123
1124hashalg_fail:
1125 crypto_free_shash(hmacalg);
1126 return ret;
1127}
1128
1129static int __init init_trusted(void)
1130{
1131 int ret;
1132
1133 ret = trusted_shash_alloc();
1134 if (ret < 0)
1135 return ret;
1136 ret = register_key_type(&key_type_trusted);
1137 if (ret < 0)
1138 trusted_shash_release();
1139 return ret;
1140}
1141
1142static void __exit cleanup_trusted(void)
1143{
1144 trusted_shash_release();
1145 unregister_key_type(&key_type_trusted);
1146}
1147
1148late_initcall(init_trusted);
1149module_exit(cleanup_trusted);
1150
1151MODULE_LICENSE("GPL");
diff --git a/security/keys/trusted_defined.h b/security/keys/trusted_defined.h
new file mode 100644
index 000000000000..3249fbd2b653
--- /dev/null
+++ b/security/keys/trusted_defined.h
@@ -0,0 +1,134 @@
1#ifndef __TRUSTED_KEY_H
2#define __TRUSTED_KEY_H
3
4/* implementation specific TPM constants */
5#define MAX_PCRINFO_SIZE 64
6#define MAX_BUF_SIZE 512
7#define TPM_GETRANDOM_SIZE 14
8#define TPM_OSAP_SIZE 36
9#define TPM_OIAP_SIZE 10
10#define TPM_SEAL_SIZE 87
11#define TPM_UNSEAL_SIZE 104
12#define TPM_SIZE_OFFSET 2
13#define TPM_RETURN_OFFSET 6
14#define TPM_DATA_OFFSET 10
15
16#define LOAD32(buffer, offset) (ntohl(*(uint32_t *)&buffer[offset]))
17#define LOAD32N(buffer, offset) (*(uint32_t *)&buffer[offset])
18#define LOAD16(buffer, offset) (ntohs(*(uint16_t *)&buffer[offset]))
19
20struct tpm_buf {
21 int len;
22 unsigned char data[MAX_BUF_SIZE];
23};
24
25#define INIT_BUF(tb) (tb->len = 0)
26
27struct osapsess {
28 uint32_t handle;
29 unsigned char secret[SHA1_DIGEST_SIZE];
30 unsigned char enonce[TPM_NONCE_SIZE];
31};
32
33/* discrete values, but have to store in uint16_t for TPM use */
34enum {
35 SEAL_keytype = 1,
36 SRK_keytype = 4
37};
38
39struct trusted_key_options {
40 uint16_t keytype;
41 uint32_t keyhandle;
42 unsigned char keyauth[SHA1_DIGEST_SIZE];
43 unsigned char blobauth[SHA1_DIGEST_SIZE];
44 uint32_t pcrinfo_len;
45 unsigned char pcrinfo[MAX_PCRINFO_SIZE];
46 int pcrlock;
47};
48
49#define TPM_DEBUG 0
50
51#if TPM_DEBUG
52static inline void dump_options(struct trusted_key_options *o)
53{
54 pr_info("trusted_key: sealing key type %d\n", o->keytype);
55 pr_info("trusted_key: sealing key handle %0X\n", o->keyhandle);
56 pr_info("trusted_key: pcrlock %d\n", o->pcrlock);
57 pr_info("trusted_key: pcrinfo %d\n", o->pcrinfo_len);
58 print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE,
59 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
60}
61
62static inline void dump_payload(struct trusted_key_payload *p)
63{
64 pr_info("trusted_key: key_len %d\n", p->key_len);
65 print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
66 16, 1, p->key, p->key_len, 0);
67 pr_info("trusted_key: bloblen %d\n", p->blob_len);
68 print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
69 16, 1, p->blob, p->blob_len, 0);
70 pr_info("trusted_key: migratable %d\n", p->migratable);
71}
72
73static inline void dump_sess(struct osapsess *s)
74{
75 print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE,
76 16, 1, &s->handle, 4, 0);
77 pr_info("trusted-key: secret:\n");
78 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
79 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
80 pr_info("trusted-key: enonce:\n");
81 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
82 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
83}
84
85static inline void dump_tpm_buf(unsigned char *buf)
86{
87 int len;
88
89 pr_info("\ntrusted-key: tpm buffer\n");
90 len = LOAD32(buf, TPM_SIZE_OFFSET);
91 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
92}
93#else
94static inline void dump_options(struct trusted_key_options *o)
95{
96}
97
98static inline void dump_payload(struct trusted_key_payload *p)
99{
100}
101
102static inline void dump_sess(struct osapsess *s)
103{
104}
105
106static inline void dump_tpm_buf(unsigned char *buf)
107{
108}
109#endif
110
111static inline void store8(struct tpm_buf *buf, const unsigned char value)
112{
113 buf->data[buf->len++] = value;
114}
115
116static inline void store16(struct tpm_buf *buf, const uint16_t value)
117{
118 *(uint16_t *) & buf->data[buf->len] = htons(value);
119 buf->len += sizeof value;
120}
121
122static inline void store32(struct tpm_buf *buf, const uint32_t value)
123{
124 *(uint32_t *) & buf->data[buf->len] = htonl(value);
125 buf->len += sizeof value;
126}
127
128static inline void storebytes(struct tpm_buf *buf, const unsigned char *in,
129 const int len)
130{
131 memcpy(buf->data + buf->len, in, len);
132 buf->len += len;
133}
134#endif