Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(686)

Side by Side Diff: content/child/webcrypto/nss/rsa_oaep_nss.cc

Issue 379383002: Refactor WebCrypto code (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase onto master Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium 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 #include <cryptohi.h>
6 #include <keyhi.h>
7 #include <pk11pub.h>
8 #include <secerr.h>
9 #include <sechash.h>
10
11 #include "content/child/webcrypto/crypto_data.h"
12 #include "content/child/webcrypto/nss/key_nss.h"
13 #include "content/child/webcrypto/nss/rsa_key_nss.h"
14 #include "content/child/webcrypto/nss/util_nss.h"
15 #include "content/child/webcrypto/status.h"
16 #include "content/child/webcrypto/webcrypto_util.h"
17 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
18 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
19
20 namespace content {
21
22 namespace webcrypto {
23
24 namespace {
25
26 Status NssSupportsRsaOaep() {
27 if (NssRuntimeSupport::Get()->IsRsaOaepSupported())
28 return Status::Success();
29 return Status::ErrorUnsupported(
30 "NSS version doesn't support RSA-OAEP. Try using version 3.16.2 or "
31 "later");
32 }
33
34 CK_MECHANISM_TYPE WebCryptoHashToMGFMechanism(
35 const blink::WebCryptoAlgorithm& algorithm) {
36 switch (algorithm.id()) {
37 case blink::WebCryptoAlgorithmIdSha1:
38 return CKG_MGF1_SHA1;
39 case blink::WebCryptoAlgorithmIdSha256:
40 return CKG_MGF1_SHA256;
41 case blink::WebCryptoAlgorithmIdSha384:
42 return CKG_MGF1_SHA384;
43 case blink::WebCryptoAlgorithmIdSha512:
44 return CKG_MGF1_SHA512;
45 default:
46 return CKM_INVALID_MECHANISM;
47 }
48 }
49
50 CK_MECHANISM_TYPE WebCryptoHashToDigestMechanism(
51 const blink::WebCryptoAlgorithm& algorithm) {
52 switch (algorithm.id()) {
53 case blink::WebCryptoAlgorithmIdSha1:
54 return CKM_SHA_1;
55 case blink::WebCryptoAlgorithmIdSha256:
56 return CKM_SHA256;
57 case blink::WebCryptoAlgorithmIdSha384:
58 return CKM_SHA384;
59 case blink::WebCryptoAlgorithmIdSha512:
60 return CKM_SHA512;
61 default:
62 // Not a supported algorithm.
63 return CKM_INVALID_MECHANISM;
64 }
65 }
66
67 bool InitializeRsaOaepParams(const blink::WebCryptoAlgorithm& hash,
68 const CryptoData& label,
69 CK_RSA_PKCS_OAEP_PARAMS* oaep_params) {
70 oaep_params->source = CKZ_DATA_SPECIFIED;
71 oaep_params->pSourceData = const_cast<unsigned char*>(label.bytes());
72 oaep_params->ulSourceDataLen = label.byte_length();
73 oaep_params->mgf = WebCryptoHashToMGFMechanism(hash);
74 oaep_params->hashAlg = WebCryptoHashToDigestMechanism(hash);
75
76 if (oaep_params->mgf == CKM_INVALID_MECHANISM ||
77 oaep_params->hashAlg == CKM_INVALID_MECHANISM) {
78 return false;
79 }
80
81 return true;
82 }
83
84 Status EncryptRsaOaep(SECKEYPublicKey* key,
85 const blink::WebCryptoAlgorithm& hash,
86 const CryptoData& label,
87 const CryptoData& data,
88 std::vector<uint8>* buffer) {
89 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0};
90 if (!InitializeRsaOaepParams(hash, label, &oaep_params))
91 return Status::ErrorUnsupported();
92
93 SECItem param;
94 param.type = siBuffer;
95 param.data = reinterpret_cast<unsigned char*>(&oaep_params);
96 param.len = sizeof(oaep_params);
97
98 buffer->resize(SECKEY_PublicKeyStrength(key));
99 unsigned char* buffer_data = Uint8VectorStart(buffer);
100 unsigned int output_len;
101 if (NssRuntimeSupport::Get()->pk11_pub_encrypt_func()(key,
102 CKM_RSA_PKCS_OAEP,
103 &param,
104 buffer_data,
105 &output_len,
106 buffer->size(),
107 data.bytes(),
108 data.byte_length(),
109 NULL) != SECSuccess) {
110 return Status::OperationError();
111 }
112
113 DCHECK_LE(output_len, buffer->size());
Ryan Sleevi 2014/07/17 00:06:54 CHECK?
eroman 2014/07/17 20:37:26 Done. Thanks for reading through everything in de
114 buffer->resize(output_len);
115 return Status::Success();
116 }
117
118 Status DecryptRsaOaep(SECKEYPrivateKey* key,
119 const blink::WebCryptoAlgorithm& hash,
120 const CryptoData& label,
121 const CryptoData& data,
122 std::vector<uint8>* buffer) {
123 Status status = NssSupportsRsaOaep();
124 if (status.IsError())
125 return status;
126
127 CK_RSA_PKCS_OAEP_PARAMS oaep_params = {0};
128 if (!InitializeRsaOaepParams(hash, label, &oaep_params))
129 return Status::ErrorUnsupported();
130
131 SECItem param;
132 param.type = siBuffer;
133 param.data = reinterpret_cast<unsigned char*>(&oaep_params);
134 param.len = sizeof(oaep_params);
135
136 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key);
137 if (modulus_length_bytes <= 0)
138 return Status::ErrorUnexpected();
139
140 buffer->resize(modulus_length_bytes);
141
142 unsigned char* buffer_data = Uint8VectorStart(buffer);
143 unsigned int output_len;
144 if (NssRuntimeSupport::Get()->pk11_priv_decrypt_func()(key,
145 CKM_RSA_PKCS_OAEP,
146 &param,
147 buffer_data,
148 &output_len,
149 buffer->size(),
150 data.bytes(),
151 data.byte_length()) !=
152 SECSuccess) {
153 return Status::OperationError();
154 }
155
156 DCHECK_LE(output_len, buffer->size());
Ryan Sleevi 2014/07/17 00:06:54 CHECK?
eroman 2014/07/17 20:37:26 Done.
157 buffer->resize(output_len);
158 return Status::Success();
159 }
160
161 class RsaOaepImplementation : public RsaHashedAlgorithm {
162 public:
163 RsaOaepImplementation()
164 : RsaHashedAlgorithm(
165 CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP,
166 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageWrapKey,
167 blink::WebCryptoKeyUsageDecrypt |
168 blink::WebCryptoKeyUsageUnwrapKey) {}
169
170 virtual Status VerifyKeyUsagesBeforeGenerateKeyPair(
171 blink::WebCryptoKeyUsageMask combined_usage_mask,
172 blink::WebCryptoKeyUsageMask* public_usage_mask,
173 blink::WebCryptoKeyUsageMask* private_usage_mask) const OVERRIDE {
174 Status status = NssSupportsRsaOaep();
175 if (status.IsError())
176 return status;
177 return RsaHashedAlgorithm::VerifyKeyUsagesBeforeGenerateKeyPair(
178 combined_usage_mask, public_usage_mask, private_usage_mask);
179 }
180
181 virtual Status VerifyKeyUsagesBeforeImportKey(
182 blink::WebCryptoKeyFormat format,
183 blink::WebCryptoKeyUsageMask usage_mask) const OVERRIDE {
184 Status status = NssSupportsRsaOaep();
185 if (status.IsError())
186 return status;
187 return RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey(format,
188 usage_mask);
189 }
190
191 virtual const char* GetJwkAlgorithm(
192 const blink::WebCryptoAlgorithmId hash) const OVERRIDE {
193 switch (hash) {
194 case blink::WebCryptoAlgorithmIdSha1:
195 return "RSA-OAEP";
196 case blink::WebCryptoAlgorithmIdSha256:
197 return "RSA-OAEP-256";
198 case blink::WebCryptoAlgorithmIdSha384:
199 return "RSA-OAEP-384";
200 case blink::WebCryptoAlgorithmIdSha512:
201 return "RSA-OAEP-512";
202 default:
203 return NULL;
204 }
205 }
206
207 virtual Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
208 const blink::WebCryptoKey& key,
209 const CryptoData& data,
210 std::vector<uint8>* buffer) const OVERRIDE {
211 if (key.type() != blink::WebCryptoKeyTypePublic)
212 return Status::ErrorUnexpectedKeyType();
213
214 return EncryptRsaOaep(
215 PublicKeyNss::Cast(key)->key(),
216 key.algorithm().rsaHashedParams()->hash(),
217 CryptoData(algorithm.rsaOaepParams()->optionalLabel()),
218 data,
219 buffer);
220 }
221
222 virtual Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
223 const blink::WebCryptoKey& key,
224 const CryptoData& data,
225 std::vector<uint8>* buffer) const OVERRIDE {
226 if (key.type() != blink::WebCryptoKeyTypePrivate)
227 return Status::ErrorUnexpectedKeyType();
228
229 return DecryptRsaOaep(
230 PrivateKeyNss::Cast(key)->key(),
231 key.algorithm().rsaHashedParams()->hash(),
232 CryptoData(algorithm.rsaOaepParams()->optionalLabel()),
233 data,
234 buffer);
235 }
236 };
237
238 } // namespace
239
240 AlgorithmImplementation* CreatePlatformRsaOaepImplementation() {
241 return new RsaOaepImplementation;
242 }
243
244 } // namespace webcrypto
245
246 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698