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

Side by Side Diff: components/webcrypto/algorithms/hmac.cc

Issue 1355873002: [refactor] More post-NSS WebCrypto cleanups (utility functions). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix bug Created 5 years, 3 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <openssl/hmac.h> 5 #include <openssl/hmac.h>
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/numerics/safe_math.h"
8 #include "base/stl_util.h" 9 #include "base/stl_util.h"
9 #include "components/webcrypto/algorithm_implementation.h" 10 #include "components/webcrypto/algorithm_implementation.h"
11 #include "components/webcrypto/algorithms/secret_key_util.h"
10 #include "components/webcrypto/algorithms/util_openssl.h" 12 #include "components/webcrypto/algorithms/util_openssl.h"
11 #include "components/webcrypto/crypto_data.h" 13 #include "components/webcrypto/crypto_data.h"
12 #include "components/webcrypto/jwk.h" 14 #include "components/webcrypto/jwk.h"
13 #include "components/webcrypto/key.h" 15 #include "components/webcrypto/key.h"
14 #include "components/webcrypto/status.h" 16 #include "components/webcrypto/status.h"
15 #include "components/webcrypto/webcrypto_util.h" 17 #include "components/webcrypto/webcrypto_util.h"
16 #include "crypto/openssl_util.h" 18 #include "crypto/openssl_util.h"
17 #include "crypto/secure_util.h" 19 #include "crypto/secure_util.h"
18 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" 20 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
19 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" 21 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
20 22
21 namespace webcrypto { 23 namespace webcrypto {
22 24
23 namespace { 25 namespace {
24 26
27 Status GetShaBlockSizeBits(const blink::WebCryptoAlgorithm& algorithm,
28 unsigned int* block_size_bits) {
29 switch (algorithm.id()) {
30 case blink::WebCryptoAlgorithmIdSha1:
31 case blink::WebCryptoAlgorithmIdSha256:
32 *block_size_bits = 512;
33 return Status::Success();
34 case blink::WebCryptoAlgorithmIdSha384:
35 case blink::WebCryptoAlgorithmIdSha512:
36 *block_size_bits = 1024;
davidben 2015/09/18 22:15:59 Probably for later, but OpenSSL knows this already
eroman 2015/09/18 23:13:23 Thanks, I will look at that in a follow-up! For no
37 return Status::Success();
38 default:
39 return Status::ErrorUnsupported();
40 }
41 }
42
43 // Gets the requested key length in bits for an HMAC import operation.
44 Status GetHmacImportKeyLengthBits(
45 const blink::WebCryptoHmacImportParams* params,
46 unsigned int key_data_byte_length,
47 unsigned int* keylen_bits) {
48 if (key_data_byte_length == 0)
49 return Status::ErrorHmacImportEmptyKey();
50
51 // Make sure that the key data's length can be represented in bits without
52 // overflow.
53 base::CheckedNumeric<unsigned int> checked_keylen_bits(key_data_byte_length);
54 checked_keylen_bits *= 8;
55
56 if (!checked_keylen_bits.IsValid())
57 return Status::ErrorDataTooLarge();
58
59 unsigned int data_keylen_bits = checked_keylen_bits.ValueOrDie();
60
61 // Determine how many bits of the input to use.
62 *keylen_bits = data_keylen_bits;
63 if (params->hasLengthBits()) {
64 // The requested bit length must be:
65 // * No longer than the input data length
66 // * At most 7 bits shorter.
67 if (NumBitsToBytes(params->optionalLengthBits()) != key_data_byte_length)
68 return Status::ErrorHmacImportBadLength();
69 *keylen_bits = params->optionalLengthBits();
70 }
71
72 return Status::Success();
73 }
74
25 const char* GetJwkHmacAlgorithmName(blink::WebCryptoAlgorithmId hash) { 75 const char* GetJwkHmacAlgorithmName(blink::WebCryptoAlgorithmId hash) {
26 switch (hash) { 76 switch (hash) {
27 case blink::WebCryptoAlgorithmIdSha1: 77 case blink::WebCryptoAlgorithmIdSha1:
28 return "HS1"; 78 return "HS1";
29 case blink::WebCryptoAlgorithmIdSha256: 79 case blink::WebCryptoAlgorithmIdSha256:
30 return "HS256"; 80 return "HS256";
31 case blink::WebCryptoAlgorithmIdSha384: 81 case blink::WebCryptoAlgorithmIdSha384:
32 return "HS384"; 82 return "HS384";
33 case blink::WebCryptoAlgorithmIdSha512: 83 case blink::WebCryptoAlgorithmIdSha512:
34 return "HS512"; 84 return "HS512";
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 blink::WebCryptoKeyUsageMask usages, 124 blink::WebCryptoKeyUsageMask usages,
75 GenerateKeyResult* result) const override { 125 GenerateKeyResult* result) const override {
76 Status status = CheckKeyCreationUsages(kAllKeyUsages, usages, false); 126 Status status = CheckKeyCreationUsages(kAllKeyUsages, usages, false);
77 if (status.IsError()) 127 if (status.IsError())
78 return status; 128 return status;
79 129
80 const blink::WebCryptoHmacKeyGenParams* params = 130 const blink::WebCryptoHmacKeyGenParams* params =
81 algorithm.hmacKeyGenParams(); 131 algorithm.hmacKeyGenParams();
82 132
83 unsigned int keylen_bits = 0; 133 unsigned int keylen_bits = 0;
84 status = GetHmacKeyGenLengthInBits(params, &keylen_bits); 134 if (params->hasLengthBits()) {
85 if (status.IsError()) 135 keylen_bits = params->optionalLengthBits();
86 return status; 136 // Zero-length HMAC keys are disallowed by the spec.
137 if (keylen_bits == 0)
138 return Status::ErrorGenerateHmacKeyLengthZero();
139 } else {
140 status = GetShaBlockSizeBits(params->hash(), &keylen_bits);
141 if (status.IsError())
142 return status;
143 }
87 144
88 return GenerateWebCryptoSecretKey(blink::WebCryptoKeyAlgorithm::createHmac( 145 return GenerateWebCryptoSecretKey(blink::WebCryptoKeyAlgorithm::createHmac(
89 params->hash().id(), keylen_bits), 146 params->hash().id(), keylen_bits),
90 extractable, usages, keylen_bits, result); 147 extractable, usages, keylen_bits, result);
91 } 148 }
92 149
93 Status VerifyKeyUsagesBeforeImportKey( 150 Status VerifyKeyUsagesBeforeImportKey(
94 blink::WebCryptoKeyFormat format, 151 blink::WebCryptoKeyFormat format,
95 blink::WebCryptoKeyUsageMask usages) const override { 152 blink::WebCryptoKeyUsageMask usages) const override {
96 switch (format) { 153 switch (format) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 bool extractable, 196 bool extractable,
140 blink::WebCryptoKeyUsageMask usages, 197 blink::WebCryptoKeyUsageMask usages,
141 blink::WebCryptoKey* key) const override { 198 blink::WebCryptoKey* key) const override {
142 const char* algorithm_name = 199 const char* algorithm_name =
143 GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id()); 200 GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id());
144 if (!algorithm_name) 201 if (!algorithm_name)
145 return Status::ErrorUnexpected(); 202 return Status::ErrorUnexpected();
146 203
147 std::vector<uint8_t> raw_data; 204 std::vector<uint8_t> raw_data;
148 JwkReader jwk; 205 JwkReader jwk;
149 Status status = ReadSecretKeyNoExpectedAlg(key_data, extractable, usages, 206 Status status = ReadSecretKeyNoExpectedAlgJwk(key_data, extractable, usages,
150 &raw_data, &jwk); 207 &raw_data, &jwk);
151 if (status.IsError()) 208 if (status.IsError())
152 return status; 209 return status;
153 status = jwk.VerifyAlg(algorithm_name); 210 status = jwk.VerifyAlg(algorithm_name);
154 if (status.IsError()) 211 if (status.IsError())
155 return status; 212 return status;
156 213
157 return ImportKeyRaw(CryptoData(raw_data), algorithm, extractable, usages, 214 return ImportKeyRaw(CryptoData(raw_data), algorithm, extractable, usages,
158 key); 215 key);
159 } 216 }
160 217
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 blink::WebCryptoKeyUsageMask usages, 272 blink::WebCryptoKeyUsageMask usages,
216 const CryptoData& key_data, 273 const CryptoData& key_data,
217 blink::WebCryptoKey* key) const override { 274 blink::WebCryptoKey* key) const override {
218 return CreateWebCryptoSecretKey(key_data, algorithm, extractable, usages, 275 return CreateWebCryptoSecretKey(key_data, algorithm, extractable, usages,
219 key); 276 key);
220 } 277 }
221 278
222 Status GetKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm, 279 Status GetKeyLength(const blink::WebCryptoAlgorithm& key_length_algorithm,
223 bool* has_length_bits, 280 bool* has_length_bits,
224 unsigned int* length_bits) const override { 281 unsigned int* length_bits) const override {
225 return GetHmacKeyLength(key_length_algorithm, has_length_bits, length_bits); 282 const blink::WebCryptoHmacImportParams* params =
283 key_length_algorithm.hmacImportParams();
284
285 *has_length_bits = true;
286 if (params->hasLengthBits()) {
287 *length_bits = params->optionalLengthBits();
288 if (*length_bits == 0)
289 return Status::ErrorGetHmacKeyLengthZero();
290 return Status::Success();
291 }
292
293 return GetShaBlockSizeBits(params->hash(), length_bits);
226 } 294 }
227 }; 295 };
228 296
229 } // namespace 297 } // namespace
230 298
231 scoped_ptr<AlgorithmImplementation> CreateHmacImplementation() { 299 scoped_ptr<AlgorithmImplementation> CreateHmacImplementation() {
232 return make_scoped_ptr(new HmacImplementation); 300 return make_scoped_ptr(new HmacImplementation);
233 } 301 }
234 302
235 } // namespace webcrypto 303 } // namespace webcrypto
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698