• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * Miscellaneous functions for userspace vboot utilities.
6  */
7 
8 #include <openssl/bn.h>
9 #include <openssl/rsa.h>
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 
16 #include "cryptolib.h"
17 #include "host_common.h"
18 #include "util_misc.h"
19 #include "vboot_common.h"
20 
PrintPubKeySha1Sum(VbPublicKey * key)21 void PrintPubKeySha1Sum(VbPublicKey *key)
22 {
23 	uint8_t *buf = ((uint8_t *)key) + key->key_offset;
24 	uint64_t buflen = key->key_size;
25 	uint8_t *digest = DigestBuf(buf, buflen, SHA1_DIGEST_ALGORITHM);
26 	int i;
27 	for (i = 0; i < SHA1_DIGEST_SIZE; i++)
28 		printf("%02x", digest[i]);
29 	free(digest);
30 }
31 
vb_keyb_from_rsa(struct rsa_st * rsa_private_key,uint8_t ** keyb_data,uint32_t * keyb_size)32 int vb_keyb_from_rsa(struct rsa_st *rsa_private_key,
33 		     uint8_t **keyb_data, uint32_t *keyb_size)
34 {
35 	uint32_t i, nwords;
36 	BIGNUM *N = NULL;
37 	BIGNUM *Big1 = NULL, *Big2 = NULL, *Big32 = NULL, *BigMinus1 = NULL;
38 	BIGNUM *B = NULL;
39 	BIGNUM *N0inv = NULL, *R = NULL, *RR = NULL;
40 	BIGNUM *RRTemp = NULL, *NnumBits = NULL;
41 	BIGNUM *n = NULL, *rr = NULL;
42 	BN_CTX *bn_ctx = BN_CTX_new();
43 	uint32_t n0invout;
44 	uint32_t bufsize;
45 	uint32_t *outbuf;
46 	int retval = 1;
47 
48 	/* Size of RSA key in 32-bit words */
49 	nwords = BN_num_bits(rsa_private_key->n) / 32;
50 
51 	bufsize = (2 + nwords + nwords) * sizeof(uint32_t);
52 	outbuf = malloc(bufsize);
53 	if (!outbuf)
54 		goto done;
55 
56 	*keyb_data = (uint8_t *)outbuf;
57 	*keyb_size = bufsize;
58 
59 	*outbuf++ = nwords;
60 
61 	/* Initialize BIGNUMs */
62 #define NEW_BIGNUM(x) do { x = BN_new(); if (!x) goto done; } while (0)
63 	NEW_BIGNUM(N);
64 	NEW_BIGNUM(Big1);
65 	NEW_BIGNUM(Big2);
66 	NEW_BIGNUM(Big32);
67 	NEW_BIGNUM(BigMinus1);
68 	NEW_BIGNUM(N0inv);
69 	NEW_BIGNUM(R);
70 	NEW_BIGNUM(RR);
71 	NEW_BIGNUM(RRTemp);
72 	NEW_BIGNUM(NnumBits);
73 	NEW_BIGNUM(n);
74 	NEW_BIGNUM(rr);
75 	NEW_BIGNUM(B);
76 #undef NEW_BIGNUM
77 
78 	BN_copy(N, rsa_private_key->n);
79 	BN_set_word(Big1, 1L);
80 	BN_set_word(Big2, 2L);
81 	BN_set_word(Big32, 32L);
82 	BN_sub(BigMinus1, Big1, Big2);
83 
84 	BN_exp(B, Big2, Big32, bn_ctx); /* B = 2^32 */
85 
86 	/* Calculate and output N0inv = -1 / N[0] mod 2^32 */
87 	BN_mod_inverse(N0inv, N, B, bn_ctx);
88 	BN_sub(N0inv, B, N0inv);
89 	n0invout = BN_get_word(N0inv);
90 
91 	*outbuf++ = n0invout;
92 
93 	/* Calculate R = 2^(# of key bits) */
94 	BN_set_word(NnumBits, BN_num_bits(N));
95 	BN_exp(R, Big2, NnumBits, bn_ctx);
96 
97 	/* Calculate RR = R^2 mod N */
98 	BN_copy(RR, R);
99 	BN_mul(RRTemp, RR, R, bn_ctx);
100 	BN_mod(RR, RRTemp, N, bn_ctx);
101 
102 
103 	/* Write out modulus as little endian array of integers. */
104 	for (i = 0; i < nwords; ++i) {
105 		uint32_t nout;
106 
107 		BN_mod(n, N, B, bn_ctx); /* n = N mod B */
108 		nout = BN_get_word(n);
109 		*outbuf++ = nout;
110 
111 		BN_rshift(N, N, 32); /*  N = N/B */
112 	}
113 
114 	/* Write R^2 as little endian array of integers. */
115 	for (i = 0; i < nwords; ++i) {
116 		uint32_t rrout;
117 
118 		BN_mod(rr, RR, B, bn_ctx); /* rr = RR mod B */
119 		rrout = BN_get_word(rr);
120 		*outbuf++ = rrout;
121 
122 		BN_rshift(RR, RR, 32); /* RR = RR/B */
123 	}
124 
125 	outbuf = NULL;
126 	retval = 0;
127 
128 done:
129 	free(outbuf);
130 	/* Free BIGNUMs. */
131 	BN_free(Big1);
132 	BN_free(Big2);
133 	BN_free(Big32);
134 	BN_free(BigMinus1);
135 	BN_free(N0inv);
136 	BN_free(R);
137 	BN_free(RRTemp);
138 	BN_free(NnumBits);
139 	BN_free(n);
140 	BN_free(rr);
141 
142 	return retval;
143 }
144