1d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler * Use of this source code is governed by a BSD-style license that can be
3d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler * found in the LICENSE file.
4d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler *
5d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler * Key unpacking functions
6d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler */
7d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
8d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler#include "2sysincludes.h"
9d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler#include "2common.h"
10d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler#include "2rsa.h"
11108d991c678f80c99967bd07035de7418c81a072Randall Spangler#include "vb2_common.h"
12d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
13308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spanglerint vb2_unpack_key_data(struct vb2_public_key *key,
1459c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler			 const uint8_t *key_data,
1559c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler			 uint32_t key_size)
16d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler{
1759c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	const uint32_t *buf32 = (const uint32_t *)key_data;
1859c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	uint32_t expected_key_size = vb2_packed_key_size(key->sig_alg);
1959c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler
2059c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	/* Make sure buffer is the correct length */
2159c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	if (!expected_key_size || expected_key_size != key_size) {
2259c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler		VB2_DEBUG("Wrong key size for algorithm\n");
2359c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler		return VB2_ERROR_UNPACK_KEY_SIZE;
2459c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	}
2559c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler
2659c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	/* Check for alignment */
2759c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	if (!vb2_aligned(buf32, sizeof(uint32_t)))
2859c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler		return VB2_ERROR_UNPACK_KEY_ALIGN;
2959c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler
3059c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	key->arrsize = buf32[0];
3159c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler
3259c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	/* Sanity check key array size */
3359c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	if (key->arrsize * sizeof(uint32_t) != vb2_rsa_sig_size(key->sig_alg))
3459c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler		return VB2_ERROR_UNPACK_KEY_ARRAY_SIZE;
3559c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler
3659c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	key->n0inv = buf32[1];
3759c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler
3859c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	/* Arrays point inside the key data */
3959c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	key->n = buf32 + 2;
4059c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	key->rr = buf32 + 2 + key->arrsize;
4159c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler
4259c29202d2d67b97f587152b5457ed89f7430a77Randall Spangler	return VB2_SUCCESS;
43d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler}
44d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
45308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spanglerint vb2_unpack_key(struct vb2_public_key *key,
46d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler		    const uint8_t *buf,
47d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler		    uint32_t size)
48d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler{
49308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler	const struct vb2_packed_key *pkey =
50308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler		(const struct vb2_packed_key *)buf;
51d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	uint32_t sig_size;
526b5b8f65d52bc91ca37e5cb484867251d81136b1Randall Spangler	uint32_t min_offset = 0;
53d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	int rv;
54d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
557aef90c14d9dc770b4e16876faf8bf6b9942ff2eChromeOS Developer	/* Check magic number */
56308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler	if (pkey->c.magic != VB2_MAGIC_PACKED_KEY)
577aef90c14d9dc770b4e16876faf8bf6b9942ff2eChromeOS Developer		return VB2_ERROR_UNPACK_KEY_MAGIC;
58d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
596b5b8f65d52bc91ca37e5cb484867251d81136b1Randall Spangler	rv = vb2_verify_common_header(buf, size);
606b5b8f65d52bc91ca37e5cb484867251d81136b1Randall Spangler	if (rv)
616b5b8f65d52bc91ca37e5cb484867251d81136b1Randall Spangler		return rv;
626b5b8f65d52bc91ca37e5cb484867251d81136b1Randall Spangler
636b5b8f65d52bc91ca37e5cb484867251d81136b1Randall Spangler	/* Make sure key data is inside */
646b5b8f65d52bc91ca37e5cb484867251d81136b1Randall Spangler	rv = vb2_verify_common_member(pkey, &min_offset,
656b5b8f65d52bc91ca37e5cb484867251d81136b1Randall Spangler				      pkey->key_offset, pkey->key_size);
66d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	if (rv)
67d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler		return rv;
68d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
69d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	/*
70d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	 * Check for compatible version.  No need to check minor version, since
71d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	 * that's compatible across readers matching the major version, and we
72d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	 * haven't added any new fields.
73d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	 */
74308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler	if (pkey->c.struct_version_major != VB2_PACKED_KEY_VERSION_MAJOR)
75d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler		return VB2_ERROR_UNPACK_KEY_STRUCT_VERSION;
76d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
77d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	/* Copy key algorithms */
786300a6439e121ac41ad336c7422dcdbb0d649c7cRandall Spangler	key->hash_alg = pkey->hash_alg;
79d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	if (!vb2_digest_size(key->hash_alg))
80d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler		return VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM;
81d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
82fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler	key->sig_alg = pkey->sig_alg;
83fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler	if (key->sig_alg != VB2_SIG_NONE) {
84fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler		sig_size = vb2_rsa_sig_size(key->sig_alg);
85fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler		if (!sig_size)
86fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler			return VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM;
87308d2540929cd95e2a565be95ce0b1d45d2fbed2Randall Spangler		rv = vb2_unpack_key_data(
88fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler				key,
89fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler				(const uint8_t *)pkey + pkey->key_offset,
90fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler				pkey->key_size);
91fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler		if (rv)
92fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler			return rv;
93fb9a216dd677d97f3d6963f668a9b84d349ef339Randall Spangler	}
94d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
95d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	/* Key description */
969328bbff521625e788396ef9c5b26b79e6d1a7cbRandall Spangler	key->desc = vb2_common_desc(pkey);
97d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	key->version = pkey->key_version;
98fe21172cc315b6249e78ee8bc17d1470e8b6b02bRandall Spangler	key->guid = &pkey->guid;
99d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler
100d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler	return VB2_SUCCESS;
101d274a2e9536907d0474d988f32f602cd64ed1ae6Randall Spangler}
102