linux/security/keys/trusted-keys/trusted_tpm2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2004 IBM Corporation
   4 * Copyright (C) 2014 Intel Corporation
   5 */
   6
   7#include <linux/asn1_encoder.h>
   8#include <linux/oid_registry.h>
   9#include <linux/string.h>
  10#include <linux/err.h>
  11#include <linux/tpm.h>
  12#include <linux/tpm_command.h>
  13
  14#include <keys/trusted-type.h>
  15#include <keys/trusted_tpm.h>
  16
  17#include <asm/unaligned.h>
  18
  19#include "tpm2key.asn1.h"
  20
  21static struct tpm2_hash tpm2_hash_map[] = {
  22        {HASH_ALGO_SHA1, TPM_ALG_SHA1},
  23        {HASH_ALGO_SHA256, TPM_ALG_SHA256},
  24        {HASH_ALGO_SHA384, TPM_ALG_SHA384},
  25        {HASH_ALGO_SHA512, TPM_ALG_SHA512},
  26        {HASH_ALGO_SM3_256, TPM_ALG_SM3_256},
  27};
  28
  29static u32 tpm2key_oid[] = { 2, 23, 133, 10, 1, 5 };
  30
  31static int tpm2_key_encode(struct trusted_key_payload *payload,
  32                           struct trusted_key_options *options,
  33                           u8 *src, u32 len)
  34{
  35        const int SCRATCH_SIZE = PAGE_SIZE;
  36        u8 *scratch = kmalloc(SCRATCH_SIZE, GFP_KERNEL);
  37        u8 *work = scratch, *work1;
  38        u8 *end_work = scratch + SCRATCH_SIZE;
  39        u8 *priv, *pub;
  40        u16 priv_len, pub_len;
  41
  42        priv_len = get_unaligned_be16(src) + 2;
  43        priv = src;
  44
  45        src += priv_len;
  46
  47        pub_len = get_unaligned_be16(src) + 2;
  48        pub = src;
  49
  50        if (!scratch)
  51                return -ENOMEM;
  52
  53        work = asn1_encode_oid(work, end_work, tpm2key_oid,
  54                               asn1_oid_len(tpm2key_oid));
  55
  56        if (options->blobauth_len == 0) {
  57                unsigned char bool[3], *w = bool;
  58                /* tag 0 is emptyAuth */
  59                w = asn1_encode_boolean(w, w + sizeof(bool), true);
  60                if (WARN(IS_ERR(w), "BUG: Boolean failed to encode"))
  61                        return PTR_ERR(w);
  62                work = asn1_encode_tag(work, end_work, 0, bool, w - bool);
  63        }
  64
  65        /*
  66         * Assume both octet strings will encode to a 2 byte definite length
  67         *
  68         * Note: For a well behaved TPM, this warning should never
  69         * trigger, so if it does there's something nefarious going on
  70         */
  71        if (WARN(work - scratch + pub_len + priv_len + 14 > SCRATCH_SIZE,
  72                 "BUG: scratch buffer is too small"))
  73                return -EINVAL;
  74
  75        work = asn1_encode_integer(work, end_work, options->keyhandle);
  76        work = asn1_encode_octet_string(work, end_work, pub, pub_len);
  77        work = asn1_encode_octet_string(work, end_work, priv, priv_len);
  78
  79        work1 = payload->blob;
  80        work1 = asn1_encode_sequence(work1, work1 + sizeof(payload->blob),
  81                                     scratch, work - scratch);
  82        if (WARN(IS_ERR(work1), "BUG: ASN.1 encoder failed"))
  83                return PTR_ERR(work1);
  84
  85        return work1 - payload->blob;
  86}
  87
  88struct tpm2_key_context {
  89        u32 parent;
  90        const u8 *pub;
  91        u32 pub_len;
  92        const u8 *priv;
  93        u32 priv_len;
  94};
  95
  96static int tpm2_key_decode(struct trusted_key_payload *payload,
  97                           struct trusted_key_options *options,
  98                           u8 **buf)
  99{
 100        int ret;
 101        struct tpm2_key_context ctx;
 102        u8 *blob;
 103
 104        memset(&ctx, 0, sizeof(ctx));
 105
 106        ret = asn1_ber_decoder(&tpm2key_decoder, &ctx, payload->blob,
 107                               payload->blob_len);
 108        if (ret < 0)
 109                return ret;
 110
 111        if (ctx.priv_len + ctx.pub_len > MAX_BLOB_SIZE)
 112                return -EINVAL;
 113
 114        blob = kmalloc(ctx.priv_len + ctx.pub_len + 4, GFP_KERNEL);
 115        if (!blob)
 116                return -ENOMEM;
 117
 118        *buf = blob;
 119        options->keyhandle = ctx.parent;
 120
 121        memcpy(blob, ctx.priv, ctx.priv_len);
 122        blob += ctx.priv_len;
 123
 124        memcpy(blob, ctx.pub, ctx.pub_len);
 125
 126        return 0;
 127}
 128
 129int tpm2_key_parent(void *context, size_t hdrlen,
 130                  unsigned char tag,
 131                  const void *value, size_t vlen)
 132{
 133        struct tpm2_key_context *ctx = context;
 134        const u8 *v = value;
 135        int i;
 136
 137        ctx->parent = 0;
 138        for (i = 0; i < vlen; i++) {
 139                ctx->parent <<= 8;
 140                ctx->parent |= v[i];
 141        }
 142
 143        return 0;
 144}
 145
 146int tpm2_key_type(void *context, size_t hdrlen,
 147                unsigned char tag,
 148                const void *value, size_t vlen)
 149{
 150        enum OID oid = look_up_OID(value, vlen);
 151
 152        if (oid != OID_TPMSealedData) {
 153                char buffer[50];
 154
 155                sprint_oid(value, vlen, buffer, sizeof(buffer));
 156                pr_debug("OID is \"%s\" which is not TPMSealedData\n",
 157                         buffer);
 158                return -EINVAL;
 159        }
 160
 161        return 0;
 162}
 163
 164int tpm2_key_pub(void *context, size_t hdrlen,
 165               unsigned char tag,
 166               const void *value, size_t vlen)
 167{
 168        struct tpm2_key_context *ctx = context;
 169
 170        ctx->pub = value;
 171        ctx->pub_len = vlen;
 172
 173        return 0;
 174}
 175
 176int tpm2_key_priv(void *context, size_t hdrlen,
 177                unsigned char tag,
 178                const void *value, size_t vlen)
 179{
 180        struct tpm2_key_context *ctx = context;
 181
 182        ctx->priv = value;
 183        ctx->priv_len = vlen;
 184
 185        return 0;
 186}
 187
 188/**
 189 * tpm_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer.
 190 *
 191 * @buf: an allocated tpm_buf instance
 192 * @session_handle: session handle
 193 * @nonce: the session nonce, may be NULL if not used
 194 * @nonce_len: the session nonce length, may be 0 if not used
 195 * @attributes: the session attributes
 196 * @hmac: the session HMAC or password, may be NULL if not used
 197 * @hmac_len: the session HMAC or password length, maybe 0 if not used
 198 */
 199static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle,
 200                                 const u8 *nonce, u16 nonce_len,
 201                                 u8 attributes,
 202                                 const u8 *hmac, u16 hmac_len)
 203{
 204        tpm_buf_append_u32(buf, 9 + nonce_len + hmac_len);
 205        tpm_buf_append_u32(buf, session_handle);
 206        tpm_buf_append_u16(buf, nonce_len);
 207
 208        if (nonce && nonce_len)
 209                tpm_buf_append(buf, nonce, nonce_len);
 210
 211        tpm_buf_append_u8(buf, attributes);
 212        tpm_buf_append_u16(buf, hmac_len);
 213
 214        if (hmac && hmac_len)
 215                tpm_buf_append(buf, hmac, hmac_len);
 216}
 217
 218/**
 219 * tpm2_seal_trusted() - seal the payload of a trusted key
 220 *
 221 * @chip: TPM chip to use
 222 * @payload: the key data in clear and encrypted form
 223 * @options: authentication values and other options
 224 *
 225 * Return: < 0 on error and 0 on success.
 226 */
 227int tpm2_seal_trusted(struct tpm_chip *chip,
 228                      struct trusted_key_payload *payload,
 229                      struct trusted_key_options *options)
 230{
 231        int blob_len = 0;
 232        struct tpm_buf buf;
 233        u32 hash;
 234        u32 flags;
 235        int i;
 236        int rc;
 237
 238        for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) {
 239                if (options->hash == tpm2_hash_map[i].crypto_id) {
 240                        hash = tpm2_hash_map[i].tpm_id;
 241                        break;
 242                }
 243        }
 244
 245        if (i == ARRAY_SIZE(tpm2_hash_map))
 246                return -EINVAL;
 247
 248        if (!options->keyhandle)
 249                return -EINVAL;
 250
 251        rc = tpm_try_get_ops(chip);
 252        if (rc)
 253                return rc;
 254
 255        rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
 256        if (rc) {
 257                tpm_put_ops(chip);
 258                return rc;
 259        }
 260
 261        tpm_buf_append_u32(&buf, options->keyhandle);
 262        tpm2_buf_append_auth(&buf, TPM2_RS_PW,
 263                             NULL /* nonce */, 0,
 264                             0 /* session_attributes */,
 265                             options->keyauth /* hmac */,
 266                             TPM_DIGEST_SIZE);
 267
 268        /* sensitive */
 269        tpm_buf_append_u16(&buf, 4 + options->blobauth_len + payload->key_len);
 270
 271        tpm_buf_append_u16(&buf, options->blobauth_len);
 272        if (options->blobauth_len)
 273                tpm_buf_append(&buf, options->blobauth, options->blobauth_len);
 274
 275        tpm_buf_append_u16(&buf, payload->key_len);
 276        tpm_buf_append(&buf, payload->key, payload->key_len);
 277
 278        /* public */
 279        tpm_buf_append_u16(&buf, 14 + options->policydigest_len);
 280        tpm_buf_append_u16(&buf, TPM_ALG_KEYEDHASH);
 281        tpm_buf_append_u16(&buf, hash);
 282
 283        /* key properties */
 284        flags = 0;
 285        flags |= options->policydigest_len ? 0 : TPM2_OA_USER_WITH_AUTH;
 286        flags |= payload->migratable ? (TPM2_OA_FIXED_TPM |
 287                                        TPM2_OA_FIXED_PARENT) : 0;
 288        tpm_buf_append_u32(&buf, flags);
 289
 290        /* policy */
 291        tpm_buf_append_u16(&buf, options->policydigest_len);
 292        if (options->policydigest_len)
 293                tpm_buf_append(&buf, options->policydigest,
 294                               options->policydigest_len);
 295
 296        /* public parameters */
 297        tpm_buf_append_u16(&buf, TPM_ALG_NULL);
 298        tpm_buf_append_u16(&buf, 0);
 299
 300        /* outside info */
 301        tpm_buf_append_u16(&buf, 0);
 302
 303        /* creation PCR */
 304        tpm_buf_append_u32(&buf, 0);
 305
 306        if (buf.flags & TPM_BUF_OVERFLOW) {
 307                rc = -E2BIG;
 308                goto out;
 309        }
 310
 311        rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
 312        if (rc)
 313                goto out;
 314
 315        blob_len = be32_to_cpup((__be32 *) &buf.data[TPM_HEADER_SIZE]);
 316        if (blob_len > MAX_BLOB_SIZE) {
 317                rc = -E2BIG;
 318                goto out;
 319        }
 320        if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 4 + blob_len) {
 321                rc = -EFAULT;
 322                goto out;
 323        }
 324
 325        blob_len = tpm2_key_encode(payload, options,
 326                                   &buf.data[TPM_HEADER_SIZE + 4],
 327                                   blob_len);
 328
 329out:
 330        tpm_buf_destroy(&buf);
 331
 332        if (rc > 0) {
 333                if (tpm2_rc_value(rc) == TPM2_RC_HASH)
 334                        rc = -EINVAL;
 335                else
 336                        rc = -EPERM;
 337        }
 338        if (blob_len < 0)
 339                rc = blob_len;
 340        else
 341                payload->blob_len = blob_len;
 342
 343        tpm_put_ops(chip);
 344        return rc;
 345}
 346
 347/**
 348 * tpm2_load_cmd() - execute a TPM2_Load command
 349 *
 350 * @chip: TPM chip to use
 351 * @payload: the key data in clear and encrypted form
 352 * @options: authentication values and other options
 353 * @blob_handle: returned blob handle
 354 *
 355 * Return: 0 on success.
 356 *        -E2BIG on wrong payload size.
 357 *        -EPERM on tpm error status.
 358 *        < 0 error from tpm_send.
 359 */
 360static int tpm2_load_cmd(struct tpm_chip *chip,
 361                         struct trusted_key_payload *payload,
 362                         struct trusted_key_options *options,
 363                         u32 *blob_handle)
 364{
 365        struct tpm_buf buf;
 366        unsigned int private_len;
 367        unsigned int public_len;
 368        unsigned int blob_len;
 369        u8 *blob, *pub;
 370        int rc;
 371        u32 attrs;
 372
 373        rc = tpm2_key_decode(payload, options, &blob);
 374        if (rc) {
 375                /* old form */
 376                blob = payload->blob;
 377                payload->old_format = 1;
 378        }
 379
 380        /* new format carries keyhandle but old format doesn't */
 381        if (!options->keyhandle)
 382                return -EINVAL;
 383
 384        /* must be big enough for at least the two be16 size counts */
 385        if (payload->blob_len < 4)
 386                return -EINVAL;
 387
 388        private_len = get_unaligned_be16(blob);
 389
 390        /* must be big enough for following public_len */
 391        if (private_len + 2 + 2 > (payload->blob_len))
 392                return -E2BIG;
 393
 394        public_len = get_unaligned_be16(blob + 2 + private_len);
 395        if (private_len + 2 + public_len + 2 > payload->blob_len)
 396                return -E2BIG;
 397
 398        pub = blob + 2 + private_len + 2;
 399        /* key attributes are always at offset 4 */
 400        attrs = get_unaligned_be32(pub + 4);
 401
 402        if ((attrs & (TPM2_OA_FIXED_TPM | TPM2_OA_FIXED_PARENT)) ==
 403            (TPM2_OA_FIXED_TPM | TPM2_OA_FIXED_PARENT))
 404                payload->migratable = 0;
 405        else
 406                payload->migratable = 1;
 407
 408        blob_len = private_len + public_len + 4;
 409        if (blob_len > payload->blob_len)
 410                return -E2BIG;
 411
 412        rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD);
 413        if (rc)
 414                return rc;
 415
 416        tpm_buf_append_u32(&buf, options->keyhandle);
 417        tpm2_buf_append_auth(&buf, TPM2_RS_PW,
 418                             NULL /* nonce */, 0,
 419                             0 /* session_attributes */,
 420                             options->keyauth /* hmac */,
 421                             TPM_DIGEST_SIZE);
 422
 423        tpm_buf_append(&buf, blob, blob_len);
 424
 425        if (buf.flags & TPM_BUF_OVERFLOW) {
 426                rc = -E2BIG;
 427                goto out;
 428        }
 429
 430        rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
 431        if (!rc)
 432                *blob_handle = be32_to_cpup(
 433                        (__be32 *) &buf.data[TPM_HEADER_SIZE]);
 434
 435out:
 436        if (blob != payload->blob)
 437                kfree(blob);
 438        tpm_buf_destroy(&buf);
 439
 440        if (rc > 0)
 441                rc = -EPERM;
 442
 443        return rc;
 444}
 445
 446/**
 447 * tpm2_unseal_cmd() - execute a TPM2_Unload command
 448 *
 449 * @chip: TPM chip to use
 450 * @payload: the key data in clear and encrypted form
 451 * @options: authentication values and other options
 452 * @blob_handle: blob handle
 453 *
 454 * Return: 0 on success
 455 *         -EPERM on tpm error status
 456 *         < 0 error from tpm_send
 457 */
 458static int tpm2_unseal_cmd(struct tpm_chip *chip,
 459                           struct trusted_key_payload *payload,
 460                           struct trusted_key_options *options,
 461                           u32 blob_handle)
 462{
 463        struct tpm_buf buf;
 464        u16 data_len;
 465        u8 *data;
 466        int rc;
 467
 468        rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
 469        if (rc)
 470                return rc;
 471
 472        tpm_buf_append_u32(&buf, blob_handle);
 473        tpm2_buf_append_auth(&buf,
 474                             options->policyhandle ?
 475                             options->policyhandle : TPM2_RS_PW,
 476                             NULL /* nonce */, 0,
 477                             TPM2_SA_CONTINUE_SESSION,
 478                             options->blobauth /* hmac */,
 479                             options->blobauth_len);
 480
 481        rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
 482        if (rc > 0)
 483                rc = -EPERM;
 484
 485        if (!rc) {
 486                data_len = be16_to_cpup(
 487                        (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
 488                if (data_len < MIN_KEY_SIZE ||  data_len > MAX_KEY_SIZE) {
 489                        rc = -EFAULT;
 490                        goto out;
 491                }
 492
 493                if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 6 + data_len) {
 494                        rc = -EFAULT;
 495                        goto out;
 496                }
 497                data = &buf.data[TPM_HEADER_SIZE + 6];
 498
 499                if (payload->old_format) {
 500                        /* migratable flag is at the end of the key */
 501                        memcpy(payload->key, data, data_len - 1);
 502                        payload->key_len = data_len - 1;
 503                        payload->migratable = data[data_len - 1];
 504                } else {
 505                        /*
 506                         * migratable flag already collected from key
 507                         * attributes
 508                         */
 509                        memcpy(payload->key, data, data_len);
 510                        payload->key_len = data_len;
 511                }
 512        }
 513
 514out:
 515        tpm_buf_destroy(&buf);
 516        return rc;
 517}
 518
 519/**
 520 * tpm2_unseal_trusted() - unseal the payload of a trusted key
 521 *
 522 * @chip: TPM chip to use
 523 * @payload: the key data in clear and encrypted form
 524 * @options: authentication values and other options
 525 *
 526 * Return: Same as with tpm_send.
 527 */
 528int tpm2_unseal_trusted(struct tpm_chip *chip,
 529                        struct trusted_key_payload *payload,
 530                        struct trusted_key_options *options)
 531{
 532        u32 blob_handle;
 533        int rc;
 534
 535        rc = tpm_try_get_ops(chip);
 536        if (rc)
 537                return rc;
 538
 539        rc = tpm2_load_cmd(chip, payload, options, &blob_handle);
 540        if (rc)
 541                goto out;
 542
 543        rc = tpm2_unseal_cmd(chip, payload, options, blob_handle);
 544        tpm2_flush_context(chip, blob_handle);
 545
 546out:
 547        tpm_put_ops(chip);
 548
 549        return rc;
 550}
 551