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 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 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