Home | History | Annotate | Download | only in lib21
      1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  *
      5  * Signature validation functions
      6  */
      7 
      8 #include "2sysincludes.h"
      9 #include "2common.h"
     10 #include "2rsa.h"
     11 #include "2sha.h"
     12 #include "vb2_common.h"
     13 
     14 const char *vb2_common_desc(const void *buf)
     15 {
     16 	const struct vb2_struct_common *c = buf;
     17 
     18 	return c->desc_size ? (const char *)c + c->fixed_size : "";
     19 }
     20 
     21 int vb2_verify_common_header(const void *parent, uint32_t parent_size)
     22 {
     23 	const struct vb2_struct_common *c = parent;
     24 
     25 	/* Parent buffer size must be at least the claimed total size */
     26 	if (parent_size < c->total_size)
     27 		return VB2_ERROR_COMMON_TOTAL_SIZE;
     28 
     29 	/*
     30 	 * And big enough for the fixed size, which itself must be at least as
     31 	 * big as the common struct header.
     32 	 */
     33 	if (c->total_size < c->fixed_size || c->fixed_size < sizeof(*c))
     34 		return VB2_ERROR_COMMON_FIXED_SIZE;
     35 
     36 	/* Make sure sizes are all multiples of 32 bits */
     37 	if (!vb2_aligned(c->total_size, sizeof(uint32_t)))
     38 		return VB2_ERROR_COMMON_TOTAL_UNALIGNED;
     39 	if (!vb2_aligned(c->fixed_size, sizeof(uint32_t)))
     40 		return VB2_ERROR_COMMON_FIXED_UNALIGNED;
     41 	if (!vb2_aligned(c->desc_size, sizeof(uint32_t)))
     42 		return VB2_ERROR_COMMON_DESC_UNALIGNED;
     43 
     44 	/* Check description */
     45 	if (c->desc_size > 0) {
     46 		/* Make sure description fits and doesn't wrap */
     47 		if (c->fixed_size + c->desc_size < c->fixed_size)
     48 			return VB2_ERROR_COMMON_DESC_WRAPS;
     49 		if (c->fixed_size + c->desc_size > c->total_size)
     50 			return VB2_ERROR_COMMON_DESC_SIZE;
     51 
     52 		/* Description must be null-terminated */
     53 		if (vb2_common_desc(c)[c->desc_size - 1] != 0)
     54 			return VB2_ERROR_COMMON_DESC_TERMINATOR;
     55 	}
     56 
     57 	return VB2_SUCCESS;
     58 }
     59 
     60 int vb2_verify_common_member(const void *parent,
     61 			     uint32_t *min_offset,
     62 			     uint32_t member_offset,
     63 			     uint32_t member_size)
     64 {
     65 	const struct vb2_struct_common *c = parent;
     66 	uint32_t member_end = member_offset + member_size;
     67 
     68 	/* Make sure member doesn't wrap */
     69 	if (member_end < member_offset)
     70 		return VB2_ERROR_COMMON_MEMBER_WRAPS;
     71 
     72 	/* Member offset and size must be 32-bit aligned */
     73 	if (!vb2_aligned(member_offset, sizeof(uint32_t)) ||
     74 	    !vb2_aligned(member_size, sizeof(uint32_t)))
     75 		return VB2_ERROR_COMMON_MEMBER_UNALIGNED;
     76 
     77 	/* Initialize minimum offset if necessary */
     78 	if (!*min_offset)
     79 		*min_offset = c->fixed_size + c->desc_size;
     80 
     81 	/* Member must be after minimum offset */
     82 	if (member_offset < *min_offset)
     83 		return VB2_ERROR_COMMON_MEMBER_OVERLAP;
     84 
     85 	/* Member must end before total size */
     86 	if (member_end > c->total_size)
     87 		return VB2_ERROR_COMMON_MEMBER_SIZE;
     88 
     89 	/* Update minimum offset for subsequent checks */
     90 	*min_offset = member_end;
     91 
     92 	return VB2_SUCCESS;
     93 }
     94 
     95 int vb2_verify_common_subobject(const void *parent,
     96 				uint32_t *min_offset,
     97 				uint32_t member_offset)
     98 {
     99 	const struct vb2_struct_common *p = parent;
    100 	const struct vb2_struct_common *m =
    101 		(const struct vb2_struct_common *)
    102 		((const uint8_t *)parent + member_offset);
    103 	int rv;
    104 
    105 	/*
    106 	 * Verify the parent has space at the member offset for the common
    107 	 * header.
    108 	 */
    109 	rv = vb2_verify_common_member(parent, min_offset, member_offset,
    110 				      sizeof(*m));
    111 	if (rv)
    112 		return rv;
    113 
    114 	/*
    115 	 * Now it's safe to look at the member's header, and verify any
    116 	 * additional data for the object past its common header fits in the
    117 	 * parent.
    118 	 */
    119 	rv = vb2_verify_common_header(m, p->total_size - member_offset);
    120 	if (rv)
    121 		return rv;
    122 
    123 	/* Advance the min offset to the end of the subobject */
    124 	*min_offset = member_offset + m->total_size;
    125 
    126 	return VB2_SUCCESS;
    127 }
    128 
    129 uint32_t vb2_sig_size(enum vb2_signature_algorithm sig_alg,
    130 		      enum vb2_hash_algorithm hash_alg)
    131 {
    132 	uint32_t digest_size = vb2_digest_size(hash_alg);
    133 
    134 	/* Fail if we don't support the hash algorithm */
    135 	if (!digest_size)
    136 		return 0;
    137 
    138 	/* Handle unsigned hashes */
    139 	if (sig_alg == VB2_SIG_NONE)
    140 		return digest_size;
    141 
    142 	return vb2_rsa_sig_size(sig_alg);
    143 }
    144 
    145 const struct vb2_guid *vb2_hash_guid(enum vb2_hash_algorithm hash_alg)
    146 {
    147 	switch(hash_alg) {
    148 #ifdef VB2_SUPPORT_SHA1
    149 	case VB2_HASH_SHA1:
    150 		{
    151 			static const struct vb2_guid guid = VB2_GUID_NONE_SHA1;
    152 			return &guid;
    153 		}
    154 #endif
    155 #ifdef VB2_SUPPORT_SHA256
    156 	case VB2_HASH_SHA256:
    157 		{
    158 			static const struct vb2_guid guid =
    159 				VB2_GUID_NONE_SHA256;
    160 			return &guid;
    161 		}
    162 #endif
    163 #ifdef VB2_SUPPORT_SHA512
    164 	case VB2_HASH_SHA512:
    165 		{
    166 			static const struct vb2_guid guid =
    167 				VB2_GUID_NONE_SHA512;
    168 			return &guid;
    169 		}
    170 #endif
    171 	default:
    172 		return NULL;
    173 	}
    174 }
    175 
    176 int vb2_verify_signature(const struct vb2_signature *sig, uint32_t size)
    177 {
    178 	uint32_t min_offset = 0;
    179 	uint32_t expect_sig_size;
    180 	int rv;
    181 
    182 	/* Check magic number */
    183 	if (sig->c.magic != VB2_MAGIC_SIGNATURE)
    184 		return VB2_ERROR_SIG_MAGIC;
    185 
    186 	/* Make sure common header is good */
    187 	rv = vb2_verify_common_header(sig, size);
    188 	if (rv)
    189 		return rv;
    190 
    191 	/*
    192 	 * Check for compatible version.  No need to check minor version, since
    193 	 * that's compatible across readers matching the major version, and we
    194 	 * haven't added any new fields.
    195 	 */
    196 	if (sig->c.struct_version_major != VB2_SIGNATURE_VERSION_MAJOR)
    197 		return VB2_ERROR_SIG_VERSION;
    198 
    199 	/* Make sure header is big enough for signature */
    200 	if (sig->c.fixed_size < sizeof(*sig))
    201 		return VB2_ERROR_SIG_HEADER_SIZE;
    202 
    203 	/* Make sure signature data is inside */
    204 	rv = vb2_verify_common_member(sig, &min_offset,
    205 				      sig->sig_offset, sig->sig_size);
    206 	if (rv)
    207 		return rv;
    208 
    209 	/* Make sure signature size is correct for the algorithm */
    210 	expect_sig_size = vb2_sig_size(sig->sig_alg, sig->hash_alg);
    211 	if (!expect_sig_size)
    212 		return VB2_ERROR_SIG_ALGORITHM;
    213 	if (sig->sig_size != expect_sig_size)
    214 		return VB2_ERROR_SIG_SIZE;
    215 
    216 	return VB2_SUCCESS;
    217 }
    218 
    219 /**
    220  * Return the signature data for a signature
    221  */
    222 static uint8_t *vb2_signature_data(struct vb2_signature *sig)
    223 {
    224 	return (uint8_t *)sig + sig->sig_offset;
    225 }
    226 
    227 int vb2_verify_digest(const struct vb2_public_key *key,
    228 		      struct vb2_signature *sig,
    229 		      const uint8_t *digest,
    230 		      const struct vb2_workbuf *wb)
    231 {
    232 	uint32_t key_sig_size = vb2_sig_size(key->sig_alg, key->hash_alg);
    233 
    234 	/* If we can't figure out the signature size, key algorithm was bad */
    235 	if (!key_sig_size)
    236 		return VB2_ERROR_VDATA_ALGORITHM;
    237 
    238 	/* Make sure the signature and key algorithms match */
    239 	if (key->sig_alg != sig->sig_alg || key->hash_alg != sig->hash_alg)
    240 		return VB2_ERROR_VDATA_ALGORITHM_MISMATCH;
    241 
    242 	if (sig->sig_size != key_sig_size)
    243 		return VB2_ERROR_VDATA_SIG_SIZE;
    244 
    245 	if (key->sig_alg == VB2_SIG_NONE) {
    246 		/* Bare hash */
    247 		if (vb2_safe_memcmp(vb2_signature_data(sig),
    248 				    digest, key_sig_size))
    249 			return VB2_ERROR_VDATA_VERIFY_DIGEST;
    250 
    251 		return VB2_SUCCESS;
    252 	} else {
    253 		/* RSA-signed digest */
    254 		return vb2_rsa_verify_digest(key,
    255 					     vb2_signature_data(sig),
    256 					     digest, wb);
    257 	}
    258 }
    259 
    260 int vb2_verify_data(const void *data,
    261 		    uint32_t size,
    262 		    struct vb2_signature *sig,
    263 		    const struct vb2_public_key *key,
    264 		    const struct vb2_workbuf *wb)
    265 {
    266 	struct vb2_workbuf wblocal = *wb;
    267 	struct vb2_digest_context *dc;
    268 	uint8_t *digest;
    269 	uint32_t digest_size;
    270 	int rv;
    271 
    272 	if (sig->data_size != size) {
    273 		VB2_DEBUG("Wrong amount of data signed.\n");
    274 		return VB2_ERROR_VDATA_SIZE;
    275 	}
    276 
    277 	/* Digest goes at start of work buffer */
    278 	digest_size = vb2_digest_size(key->hash_alg);
    279 	if (!digest_size)
    280 		return VB2_ERROR_VDATA_DIGEST_SIZE;
    281 
    282 	digest = vb2_workbuf_alloc(&wblocal, digest_size);
    283 	if (!digest)
    284 		return VB2_ERROR_VDATA_WORKBUF_DIGEST;
    285 
    286 	/* Hashing requires temp space for the context */
    287 	dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc));
    288 	if (!dc)
    289 		return VB2_ERROR_VDATA_WORKBUF_HASHING;
    290 
    291 	rv = vb2_digest_init(dc, key->hash_alg);
    292 	if (rv)
    293 		return rv;
    294 
    295 	rv = vb2_digest_extend(dc, data, size);
    296 	if (rv)
    297 		return rv;
    298 
    299 	rv = vb2_digest_finalize(dc, digest, digest_size);
    300 	if (rv)
    301 		return rv;
    302 
    303 	vb2_workbuf_free(&wblocal, sizeof(*dc));
    304 
    305 	return vb2_verify_digest(key, sig, digest, &wblocal);
    306 }
    307 
    308 int vb2_verify_keyblock(struct vb2_keyblock *block,
    309 			uint32_t size,
    310 			const struct vb2_public_key *key,
    311 			const struct vb2_workbuf *wb)
    312 {
    313 	uint32_t min_offset = 0, sig_offset;
    314 	int rv, i;
    315 
    316 	/* Check magic number */
    317 	if (block->c.magic != VB2_MAGIC_KEYBLOCK)
    318 		return VB2_ERROR_KEYBLOCK_MAGIC;
    319 
    320 	/* Make sure common header is good */
    321 	rv = vb2_verify_common_header(block, size);
    322 	if (rv)
    323 		return rv;
    324 
    325 	/*
    326 	 * Check for compatible version.  No need to check minor version, since
    327 	 * that's compatible across readers matching the major version, and we
    328 	 * haven't added any new fields.
    329 	 */
    330 	if (block->c.struct_version_major != VB2_KEYBLOCK_VERSION_MAJOR)
    331 		return VB2_ERROR_KEYBLOCK_HEADER_VERSION;
    332 
    333 	/* Make sure header is big enough */
    334 	if (block->c.fixed_size < sizeof(*block))
    335 		return VB2_ERROR_KEYBLOCK_SIZE;
    336 
    337 	/* Make sure data key is inside */
    338 	rv = vb2_verify_common_subobject(block, &min_offset, block->key_offset);
    339 	if (rv)
    340 		return rv;
    341 
    342 	/* Loop over signatures */
    343 	sig_offset = block->sig_offset;
    344 	for (i = 0; i < block->sig_count; i++, sig_offset = min_offset) {
    345 		struct vb2_signature *sig;
    346 
    347 		/* Make sure signature is inside keyblock */
    348 		rv = vb2_verify_common_subobject(block, &min_offset,
    349 						 sig_offset);
    350 		if (rv)
    351 			return rv;
    352 
    353 		sig = (struct vb2_signature *)((uint8_t *)block + sig_offset);
    354 
    355 		/* Verify the signature integrity */
    356 		rv = vb2_verify_signature(sig,
    357 					  block->c.total_size - sig_offset);
    358 		if (rv)
    359 			return rv;
    360 
    361 		/* Skip signature if it doesn't match the key GUID */
    362 		if (memcmp(&sig->guid, key->guid, GUID_SIZE))
    363 			continue;
    364 
    365 		/* Make sure we signed the right amount of data */
    366 		if (sig->data_size != block->sig_offset)
    367 			return VB2_ERROR_KEYBLOCK_SIGNED_SIZE;
    368 
    369 		return vb2_verify_data(block, block->sig_offset, sig, key, wb);
    370 	}
    371 
    372 	/* If we're still here, no signature matched the key GUID */
    373 	return VB2_ERROR_KEYBLOCK_SIG_GUID;
    374 }
    375 
    376 int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble,
    377 			   uint32_t size,
    378 			   const struct vb2_public_key *key,
    379 			   const struct vb2_workbuf *wb)
    380 {
    381 	struct vb2_signature *sig;
    382 	uint32_t min_offset = 0, hash_offset;
    383 	int rv, i;
    384 
    385 	/* Check magic number */
    386 	if (preamble->c.magic != VB2_MAGIC_FW_PREAMBLE)
    387 		return VB2_ERROR_PREAMBLE_MAGIC;
    388 
    389 	/* Make sure common header is good */
    390 	rv = vb2_verify_common_header(preamble, size);
    391 	if (rv)
    392 		return rv;
    393 
    394 	/*
    395 	 * Check for compatible version.  No need to check minor version, since
    396 	 * that's compatible across readers matching the major version, and we
    397 	 * haven't added any new fields.
    398 	 */
    399 	if (preamble->c.struct_version_major != VB2_FW_PREAMBLE_VERSION_MAJOR)
    400 		return VB2_ERROR_PREAMBLE_HEADER_VERSION;
    401 
    402 	/* Make sure header is big enough */
    403 	if (preamble->c.fixed_size < sizeof(*preamble))
    404 		return VB2_ERROR_PREAMBLE_SIZE;
    405 
    406 	/* Make sure all hash signatures are inside */
    407 	hash_offset = preamble->hash_offset;
    408 	for (i = 0; i < preamble->hash_count; i++, hash_offset = min_offset) {
    409 		/* Make sure signature is inside preamble */
    410 		rv = vb2_verify_common_subobject(preamble, &min_offset,
    411 						 hash_offset);
    412 		if (rv)
    413 			return rv;
    414 
    415 		sig = (struct vb2_signature *)
    416 			((uint8_t *)preamble + hash_offset);
    417 
    418 		/* Verify the signature integrity */
    419 		rv = vb2_verify_signature(
    420 				sig, preamble->c.total_size - hash_offset);
    421 		if (rv)
    422 			return rv;
    423 
    424 		/* Hashes must all be unsigned */
    425 		if (sig->sig_alg != VB2_SIG_NONE)
    426 			return VB2_ERROR_PREAMBLE_HASH_SIGNED;
    427 	}
    428 
    429 	/* Make sure signature is inside preamble */
    430 	rv = vb2_verify_common_subobject(preamble, &min_offset,
    431 					 preamble->sig_offset);
    432 	if (rv)
    433 		return rv;
    434 
    435 	/* Verify preamble signature */
    436 	sig = (struct vb2_signature *)((uint8_t *)preamble +
    437 				       preamble->sig_offset);
    438 
    439 	rv = vb2_verify_data(preamble, preamble->sig_offset, sig, key, wb);
    440 	if (rv)
    441 		return rv;
    442 
    443 	return VB2_SUCCESS;
    444 }
    445