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  * Host functions for signatures.
      6  */
      7 
      8 #include <openssl/rsa.h>
      9 
     10 #include "2sysincludes.h"
     11 #include "2common.h"
     12 #include "2rsa.h"
     13 #include "2sha.h"
     14 #include "vb2_common.h"
     15 #include "host_common.h"
     16 #include "host_key2.h"
     17 #include "host_signature2.h"
     18 #include "host_misc.h"
     19 
     20 /**
     21  * Get the digest info for a hash algorithm
     22  *
     23  * @param hash_alg	Hash algorithm
     24  * @param buf_ptr	On success, points to the digest info
     25  * @param size_ptr	On success, contains the info size in bytes
     26  * @return VB2_SUCCESS, or non-zero error code on failure.
     27  */
     28 static int vb2_digest_info(enum vb2_hash_algorithm hash_alg,
     29 			   const uint8_t **buf_ptr,
     30 			   uint32_t *size_ptr)
     31 {
     32 	*buf_ptr = NULL;
     33 	*size_ptr = 0;
     34 
     35 	switch (hash_alg) {
     36 #if VB2_SUPPORT_SHA1
     37 	case VB2_HASH_SHA1:
     38 		{
     39 			static const uint8_t info[] = {
     40 				0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
     41 				0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
     42 			};
     43 			*buf_ptr = info;
     44 			*size_ptr = sizeof(info);
     45 			return VB2_SUCCESS;
     46 		}
     47 #endif
     48 #if VB2_SUPPORT_SHA256
     49 	case VB2_HASH_SHA256:
     50 		{
     51 			static const uint8_t info[] = {
     52 				0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
     53 				0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
     54 				0x00, 0x04, 0x20
     55 			};
     56 			*buf_ptr = info;
     57 			*size_ptr = sizeof(info);
     58 			return VB2_SUCCESS;
     59 		}
     60 #endif
     61 #if VB2_SUPPORT_SHA512
     62 	case VB2_HASH_SHA512:
     63 		{
     64 			static const uint8_t info[] = {
     65 				0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
     66 				0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
     67 				0x00, 0x04, 0x40
     68 			};
     69 			*buf_ptr = info;
     70 			*size_ptr = sizeof(info);
     71 			return VB2_SUCCESS;
     72 		}
     73 #endif
     74 	default:
     75 		return VB2_ERROR_DIGEST_INFO;
     76 	}
     77 }
     78 
     79 int vb2_sign_data(struct vb2_signature **sig_ptr,
     80 		  const uint8_t *data,
     81 		  uint32_t size,
     82 		  const struct vb2_private_key *key,
     83 		  const char *desc)
     84 {
     85 	struct vb2_signature s = {
     86 		.c.magic = VB2_MAGIC_SIGNATURE,
     87 		.c.struct_version_major = VB2_SIGNATURE_VERSION_MAJOR,
     88 		.c.struct_version_minor = VB2_SIGNATURE_VERSION_MINOR,
     89 		.c.fixed_size = sizeof(s),
     90 		.sig_alg = key->sig_alg,
     91 		.hash_alg = key->hash_alg,
     92 		.data_size = size,
     93 		.guid = key->guid,
     94 	};
     95 
     96 	struct vb2_digest_context dc;
     97 	uint32_t digest_size;
     98 	const uint8_t *info = NULL;
     99 	uint32_t info_size = 0;
    100 	uint32_t sig_digest_size;
    101 	uint8_t *sig_digest;
    102 	uint8_t *buf;
    103 
    104 	*sig_ptr = NULL;
    105 
    106 	/* Use key description if no description supplied */
    107 	if (!desc)
    108 		desc = key->desc;
    109 
    110 	s.c.desc_size = vb2_desc_size(desc);
    111 
    112 	s.sig_offset = s.c.fixed_size + s.c.desc_size;
    113 	s.sig_size = vb2_sig_size(key->sig_alg, key->hash_alg);
    114 	if (!s.sig_size)
    115 		return VB2_SIGN_DATA_SIG_SIZE;
    116 
    117 	s.c.total_size = s.sig_offset + s.sig_size;
    118 
    119 	/* Determine digest size and allocate buffer */
    120 	if (s.sig_alg != VB2_SIG_NONE) {
    121 		if (vb2_digest_info(s.hash_alg, &info, &info_size))
    122 			return VB2_SIGN_DATA_DIGEST_INFO;
    123 	}
    124 
    125 	digest_size = vb2_digest_size(key->hash_alg);
    126 	if (!digest_size)
    127 		return VB2_SIGN_DATA_DIGEST_SIZE;
    128 
    129 	sig_digest_size = info_size + digest_size;
    130 	sig_digest = malloc(sig_digest_size);
    131 	if (!sig_digest)
    132 		return VB2_SIGN_DATA_DIGEST_ALLOC;
    133 
    134 	/* Prepend digest info, if any */
    135 	if (info_size)
    136 		memcpy(sig_digest, info, info_size);
    137 
    138 	/* Calculate hash digest */
    139 	if (vb2_digest_init(&dc, s.hash_alg)) {
    140 		free(sig_digest);
    141 		return VB2_SIGN_DATA_DIGEST_INIT;
    142 	}
    143 
    144 	if (vb2_digest_extend(&dc, data, size)) {
    145 		free(sig_digest);
    146 		return VB2_SIGN_DATA_DIGEST_EXTEND;
    147 	}
    148 
    149 	if (vb2_digest_finalize(&dc, sig_digest + info_size, digest_size)) {
    150 		free(sig_digest);
    151 		return VB2_SIGN_DATA_DIGEST_FINALIZE;
    152 	}
    153 
    154 	/* Allocate signature buffer and copy header */
    155 	buf = calloc(1, s.c.total_size);
    156 	memcpy(buf, &s, sizeof(s));
    157 
    158 	/* strcpy() is ok because we allocated buffer based on desc length */
    159 	if (desc)
    160 		strcpy((char *)buf + s.c.fixed_size, desc);
    161 
    162 	if (s.sig_alg == VB2_SIG_NONE) {
    163 		/* Bare hash signature is just the digest */
    164 		memcpy(buf + s.sig_offset, sig_digest, sig_digest_size);
    165 	} else {
    166 		/* RSA-encrypt the signature */
    167 		if (RSA_private_encrypt(sig_digest_size,
    168 					sig_digest,
    169 					buf + s.sig_offset,
    170 					key->rsa_private_key,
    171 					RSA_PKCS1_PADDING) == -1) {
    172 			free(sig_digest);
    173 			free(buf);
    174 			return VB2_SIGN_DATA_RSA_ENCRYPT;
    175 		}
    176 	}
    177 
    178 	free(sig_digest);
    179 	*sig_ptr = (struct vb2_signature *)buf;
    180 	return VB2_SUCCESS;
    181 }
    182 
    183 int vb2_sig_size_for_key(uint32_t *size_ptr,
    184 			 const struct vb2_private_key *key,
    185 			 const char *desc)
    186 {
    187 	uint32_t size = vb2_sig_size(key->sig_alg, key->hash_alg);
    188 
    189 	if (!size)
    190 		return VB2_ERROR_SIG_SIZE_FOR_KEY;
    191 
    192 	size += sizeof(struct vb2_signature);
    193 	size += vb2_desc_size(desc ? desc : key->desc);
    194 
    195 	*size_ptr = size;
    196 	return VB2_SUCCESS;
    197 }
    198 
    199 int vb2_sig_size_for_keys(uint32_t *size_ptr,
    200 			  const struct vb2_private_key **key_list,
    201 			  uint32_t key_count)
    202 {
    203 	uint32_t total = 0, size = 0;
    204 	int rv, i;
    205 
    206 	*size_ptr = 0;
    207 
    208 	for (i = 0; i < key_count; i++) {
    209 		rv = vb2_sig_size_for_key(&size, key_list[i], NULL);
    210 		if (rv)
    211 			return rv;
    212 		total += size;
    213 	}
    214 
    215 	*size_ptr = total;
    216 	return VB2_SUCCESS;
    217 }
    218 
    219 int vb2_sign_object(uint8_t *buf,
    220 		    uint32_t sig_offset,
    221 		    const struct vb2_private_key *key,
    222 		    const char *desc)
    223 {
    224 	struct vb2_struct_common *c = (struct vb2_struct_common *)buf;
    225 	struct vb2_signature *sig = NULL;
    226 	int rv;
    227 
    228 	rv = vb2_sign_data(&sig, buf, sig_offset, key, desc);
    229 	if (rv)
    230 		return rv;
    231 
    232 	if (sig_offset + sig->c.total_size > c->total_size) {
    233 		free(sig);
    234 		return VB2_SIGN_OBJECT_OVERFLOW;
    235 	}
    236 
    237 	memcpy(buf + sig_offset, sig, sig->c.total_size);
    238 	free(sig);
    239 
    240 	return VB2_SUCCESS;
    241 }
    242 
    243 int vb2_sign_object_multiple(uint8_t *buf,
    244 			     uint32_t sig_offset,
    245 			     const struct vb2_private_key **key_list,
    246 			     uint32_t key_count)
    247 {
    248 	struct vb2_struct_common *c = (struct vb2_struct_common *)buf;
    249 	uint32_t sig_next = sig_offset;
    250 	int rv, i;
    251 
    252 	for (i = 0; i < key_count; i++)	{
    253 		struct vb2_signature *sig = NULL;
    254 
    255 		rv = vb2_sign_data(&sig, buf, sig_offset, key_list[i], NULL);
    256 		if (rv)
    257 			return rv;
    258 
    259 		if (sig_next + sig->c.total_size > c->total_size) {
    260 			free(sig);
    261 			return VB2_SIGN_OBJECT_OVERFLOW;
    262 		}
    263 
    264 		memcpy(buf + sig_next, sig, sig->c.total_size);
    265 		sig_next += sig->c.total_size;
    266 		free(sig);
    267 	}
    268 
    269 	return VB2_SUCCESS;
    270 }
    271