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