blob: 95acecb90201cc52889cf2a84cf8647b3136ce2f [file] [log] [blame]
Bill Richardson78299022014-06-20 14:33:00 -07001/* 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
Adam Langley9978e0a2015-04-01 11:29:03 -07008#include <openssl/bn.h>
Bill Richardson4e4c1962015-02-03 17:07:15 -08009#include <openssl/rsa.h>
10
Bill Richardson78299022014-06-20 14:33:00 -070011#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15
Randall Spangler7c3ae422016-05-11 13:50:18 -070016#include "2sysincludes.h"
17
18#include "2common.h"
19#include "2sha.h"
Bill Richardson78299022014-06-20 14:33:00 -070020#include "host_common.h"
21#include "util_misc.h"
Randall Spangler98263a12016-06-02 16:05:49 -070022#include "vb2_common.h"
Randall Spangler158b2962016-06-03 14:00:27 -070023#include "host_key2.h"
Bill Richardson78299022014-06-20 14:33:00 -070024#include "vboot_common.h"
25
Randall Spangler98263a12016-06-02 16:05:49 -070026const char *packed_key_sha1_string(const struct vb2_packed_key *key)
Bill Richardson4e4c1962015-02-03 17:07:15 -080027{
28 uint8_t *buf = ((uint8_t *)key) + key->key_offset;
Randall Spangler98263a12016-06-02 16:05:49 -070029 uint32_t buflen = key->key_size;
Randall Spangler7c3ae422016-05-11 13:50:18 -070030 uint8_t digest[VB2_SHA1_DIGEST_SIZE];
Randall Spangler98263a12016-06-02 16:05:49 -070031 static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1];
Randall Spangler7c3ae422016-05-11 13:50:18 -070032
33 vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest));
34
Randall Spangler158b2962016-06-03 14:00:27 -070035 char *dnext = dest;
Bill Richardson4e4c1962015-02-03 17:07:15 -080036 int i;
Randall Spangler7c3ae422016-05-11 13:50:18 -070037 for (i = 0; i < sizeof(digest); i++)
Randall Spangler98263a12016-06-02 16:05:49 -070038 dnext += sprintf(dnext, "%02x", digest[i]);
39
40 return dest;
Bill Richardson4e4c1962015-02-03 17:07:15 -080041}
42
Randall Spangler158b2962016-06-03 14:00:27 -070043const char *private_key_sha1_string(const struct vb2_private_key *key)
Bill Richardson3855e2e2015-02-05 10:44:54 -080044{
Randall Spangler7c3ae422016-05-11 13:50:18 -070045 uint8_t *buf;
Bill Richardson3855e2e2015-02-05 10:44:54 -080046 uint32_t buflen;
Randall Spangler7c3ae422016-05-11 13:50:18 -070047 uint8_t digest[VB2_SHA1_DIGEST_SIZE];
Randall Spangler158b2962016-06-03 14:00:27 -070048 static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1];
Bill Richardson3855e2e2015-02-05 10:44:54 -080049
Randall Spangler158b2962016-06-03 14:00:27 -070050 if (!key->rsa_private_key ||
51 vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen)) {
52 return "<error>";
Bill Richardson3855e2e2015-02-05 10:44:54 -080053 }
54
Randall Spangler7c3ae422016-05-11 13:50:18 -070055 vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest));
56
Randall Spangler158b2962016-06-03 14:00:27 -070057 char *dnext = dest;
58 int i;
Randall Spangler7c3ae422016-05-11 13:50:18 -070059 for (i = 0; i < sizeof(digest); i++)
Randall Spangler158b2962016-06-03 14:00:27 -070060 dnext += sprintf(dnext, "%02x", digest[i]);
Bill Richardson3855e2e2015-02-05 10:44:54 -080061
Bill Richardson3855e2e2015-02-05 10:44:54 -080062 free(buf);
Randall Spangler158b2962016-06-03 14:00:27 -070063 return dest;
Bill Richardson3855e2e2015-02-05 10:44:54 -080064}
65
Bill Richardson4e4c1962015-02-03 17:07:15 -080066int vb_keyb_from_rsa(struct rsa_st *rsa_private_key,
67 uint8_t **keyb_data, uint32_t *keyb_size)
68{
69 uint32_t i, nwords;
70 BIGNUM *N = NULL;
71 BIGNUM *Big1 = NULL, *Big2 = NULL, *Big32 = NULL, *BigMinus1 = NULL;
72 BIGNUM *B = NULL;
73 BIGNUM *N0inv = NULL, *R = NULL, *RR = NULL;
74 BIGNUM *RRTemp = NULL, *NnumBits = NULL;
75 BIGNUM *n = NULL, *rr = NULL;
76 BN_CTX *bn_ctx = BN_CTX_new();
77 uint32_t n0invout;
78 uint32_t bufsize;
79 uint32_t *outbuf;
80 int retval = 1;
81
82 /* Size of RSA key in 32-bit words */
83 nwords = BN_num_bits(rsa_private_key->n) / 32;
84
85 bufsize = (2 + nwords + nwords) * sizeof(uint32_t);
86 outbuf = malloc(bufsize);
87 if (!outbuf)
88 goto done;
89
90 *keyb_data = (uint8_t *)outbuf;
91 *keyb_size = bufsize;
92
93 *outbuf++ = nwords;
94
95 /* Initialize BIGNUMs */
96#define NEW_BIGNUM(x) do { x = BN_new(); if (!x) goto done; } while (0)
97 NEW_BIGNUM(N);
98 NEW_BIGNUM(Big1);
99 NEW_BIGNUM(Big2);
100 NEW_BIGNUM(Big32);
101 NEW_BIGNUM(BigMinus1);
102 NEW_BIGNUM(N0inv);
103 NEW_BIGNUM(R);
104 NEW_BIGNUM(RR);
105 NEW_BIGNUM(RRTemp);
106 NEW_BIGNUM(NnumBits);
107 NEW_BIGNUM(n);
108 NEW_BIGNUM(rr);
109 NEW_BIGNUM(B);
110#undef NEW_BIGNUM
111
112 BN_copy(N, rsa_private_key->n);
113 BN_set_word(Big1, 1L);
114 BN_set_word(Big2, 2L);
115 BN_set_word(Big32, 32L);
116 BN_sub(BigMinus1, Big1, Big2);
117
118 BN_exp(B, Big2, Big32, bn_ctx); /* B = 2^32 */
119
120 /* Calculate and output N0inv = -1 / N[0] mod 2^32 */
121 BN_mod_inverse(N0inv, N, B, bn_ctx);
122 BN_sub(N0inv, B, N0inv);
123 n0invout = BN_get_word(N0inv);
124
125 *outbuf++ = n0invout;
126
127 /* Calculate R = 2^(# of key bits) */
128 BN_set_word(NnumBits, BN_num_bits(N));
129 BN_exp(R, Big2, NnumBits, bn_ctx);
130
131 /* Calculate RR = R^2 mod N */
132 BN_copy(RR, R);
133 BN_mul(RRTemp, RR, R, bn_ctx);
134 BN_mod(RR, RRTemp, N, bn_ctx);
135
136
137 /* Write out modulus as little endian array of integers. */
138 for (i = 0; i < nwords; ++i) {
139 uint32_t nout;
140
141 BN_mod(n, N, B, bn_ctx); /* n = N mod B */
142 nout = BN_get_word(n);
143 *outbuf++ = nout;
144
145 BN_rshift(N, N, 32); /* N = N/B */
146 }
147
148 /* Write R^2 as little endian array of integers. */
149 for (i = 0; i < nwords; ++i) {
150 uint32_t rrout;
151
152 BN_mod(rr, RR, B, bn_ctx); /* rr = RR mod B */
153 rrout = BN_get_word(rr);
154 *outbuf++ = rrout;
155
156 BN_rshift(RR, RR, 32); /* RR = RR/B */
157 }
158
159 outbuf = NULL;
160 retval = 0;
161
162done:
163 free(outbuf);
164 /* Free BIGNUMs. */
165 BN_free(Big1);
166 BN_free(Big2);
167 BN_free(Big32);
168 BN_free(BigMinus1);
169 BN_free(N0inv);
170 BN_free(R);
171 BN_free(RRTemp);
172 BN_free(NnumBits);
173 BN_free(n);
174 BN_free(rr);
175
176 return retval;
Bill Richardson78299022014-06-20 14:33:00 -0700177}