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