blob: bf322844f92d62591af9e99877811358f575d6e9 [file] [log] [blame]
Gaurav Shahe178fd92010-02-05 11:44:58 -08001/* Copyright (c) 2010 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 *
Gaurav Shah5411c7a2010-03-31 10:56:49 -07005 * Implementation of RSA utility functions.
Gaurav Shahe178fd92010-02-05 11:44:58 -08006 */
7
Gaurav Shah5411c7a2010-03-31 10:56:49 -07008#include "cryptolib.h"
Gaurav Shahe178fd92010-02-05 11:44:58 -08009#include "utility.h"
10
11int RSAProcessedKeySize(int algorithm) {
Gaurav Shahcae5fa62010-02-28 20:02:29 -080012 int key_len = siglen_map[algorithm]; /* Key length in
13 * bytes. */
Gaurav Shahe178fd92010-02-05 11:44:58 -080014 /* Total size needed by a RSAPublicKey structure is =
15 * 2 * key_len bytes for the n and rr arrays
16 * + sizeof len + sizeof n0inv.
17 */
18 return (2 * key_len + sizeof(int) + sizeof(uint32_t));
19}
20
Gaurav Shah259de402010-03-12 17:42:03 -080021RSAPublicKey* RSAPublicKeyNew(void) {
22 RSAPublicKey* key = (RSAPublicKey*) Malloc(sizeof(RSAPublicKey));
23 key->n = NULL;
24 key->rr = NULL;
25 return key;
26}
27
Gaurav Shah08df9b82010-02-23 16:16:23 -080028void RSAPublicKeyFree(RSAPublicKey* key) {
29 if (key) {
30 Free(key->n);
31 Free(key->rr);
32 Free(key);
33 }
34}
35
36RSAPublicKey* RSAPublicKeyFromBuf(const uint8_t* buf, int len) {
Gaurav Shah259de402010-03-12 17:42:03 -080037 RSAPublicKey* key = RSAPublicKeyNew();
Gaurav Shahe178fd92010-02-05 11:44:58 -080038 MemcpyState st;
39 int key_len;
40
Gaurav Shah08df9b82010-02-23 16:16:23 -080041 st.remaining_buf = (uint8_t*) buf;
Gaurav Shahe178fd92010-02-05 11:44:58 -080042 st.remaining_len = len;
Gaurav Shahe450be42010-03-29 21:27:08 -070043 st.overrun = 0;
44
Gaurav Shahe178fd92010-02-05 11:44:58 -080045 StatefulMemcpy(&st, &key->len, sizeof(key->len));
46 key_len = key->len * sizeof(uint32_t); /* key length in bytes. */
Gaurav Shah259de402010-03-12 17:42:03 -080047
48 /* Sanity Check the key length. */
49 if (RSA1024NUMBYTES != key_len &&
50 RSA2048NUMBYTES != key_len &&
51 RSA4096NUMBYTES != key_len &&
52 RSA8192NUMBYTES != key_len) {
53 RSAPublicKeyFree(key);
54 return NULL;
55 }
56
Gaurav Shahe178fd92010-02-05 11:44:58 -080057 key->n = (uint32_t*) Malloc(key_len);
58 key->rr = (uint32_t*) Malloc(key_len);
59
60 StatefulMemcpy(&st, &key->n0inv, sizeof(key->n0inv));
61 StatefulMemcpy(&st, key->n, key_len);
62 StatefulMemcpy(&st, key->rr, key_len);
Gaurav Shahe450be42010-03-29 21:27:08 -070063 if (st.overrun || st.remaining_len != 0) { /* Underrun or overrun. */
Gaurav Shah259de402010-03-12 17:42:03 -080064 RSAPublicKeyFree(key);
Gaurav Shahe178fd92010-02-05 11:44:58 -080065 return NULL;
66 }
67
68 return key;
69}
Gaurav Shah08df9b82010-02-23 16:16:23 -080070
71int RSAVerifyBinary_f(const uint8_t* key_blob,
72 const RSAPublicKey* key,
73 const uint8_t* buf,
Gaurav Shahe450be42010-03-29 21:27:08 -070074 uint64_t len,
Gaurav Shah08df9b82010-02-23 16:16:23 -080075 const uint8_t* sig,
76 int algorithm) {
77 RSAPublicKey* verification_key = NULL;
78 uint8_t* digest = NULL;
79 int key_size;
80 int sig_size;
81 int success;
82
83 if (algorithm >= kNumAlgorithms)
84 return 0; /* Invalid algorithm. */
85 key_size = RSAProcessedKeySize(algorithm);
Gaurav Shahcae5fa62010-02-28 20:02:29 -080086 sig_size = siglen_map[algorithm];
Gaurav Shah08df9b82010-02-23 16:16:23 -080087
88 if (key_blob && !key)
89 verification_key = RSAPublicKeyFromBuf(key_blob, key_size);
90 else if (!key_blob && key)
91 verification_key = (RSAPublicKey*) key; /* Supress const warning. */
92 else
93 return 0; /* Both can't be NULL or non-NULL. */
94
95 digest = DigestBuf(buf, len, algorithm);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080096 success = RSAVerify(verification_key, sig, sig_size, algorithm, digest);
Gaurav Shah08df9b82010-02-23 16:16:23 -080097
98 Free(digest);
99 if (!key)
100 RSAPublicKeyFree(verification_key); /* Only free if we allocated it. */
101 return success;
102}
Gaurav Shah463be3f2010-03-29 16:13:45 -0700103
104/* Version of RSAVerifyBinary_f() where instead of the raw binary blob
105 * of data, its digest is passed as the argument. */
106int RSAVerifyBinaryWithDigest_f(const uint8_t* key_blob,
107 const RSAPublicKey* key,
108 const uint8_t* digest,
109 const uint8_t* sig,
110 int algorithm) {
111 RSAPublicKey* verification_key = NULL;
112 int key_size;
113 int sig_size;
114 int success;
115
116 if (algorithm >= kNumAlgorithms)
117 return 0; /* Invalid algorithm. */
118 key_size = RSAProcessedKeySize(algorithm);
119 sig_size = siglen_map[algorithm];
120
121 if (key_blob && !key)
122 verification_key = RSAPublicKeyFromBuf(key_blob, key_size);
123 else if (!key_blob && key)
124 verification_key = (RSAPublicKey*) key; /* Supress const warning. */
125 else
126 return 0; /* Both can't be NULL or non-NULL. */
127
128 success = RSAVerify(verification_key, sig, sig_size, algorithm, digest);
129
130 if (!key)
131 RSAPublicKeyFree(verification_key); /* Only free if we allocated it. */
132 return success;
133}