OLD | NEW |
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 <cryptohi.h> | 5 #include <cryptohi.h> |
6 #include <pk11pub.h> | 6 #include <pk11pub.h> |
7 #include <secerr.h> | 7 #include <secerr.h> |
8 #include <sechash.h> | 8 #include <sechash.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 } | 51 } |
52 } | 52 } |
53 | 53 |
54 class HmacImplementation : public AlgorithmImplementation { | 54 class HmacImplementation : public AlgorithmImplementation { |
55 public: | 55 public: |
56 HmacImplementation() {} | 56 HmacImplementation() {} |
57 | 57 |
58 virtual Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, | 58 virtual Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, |
59 bool extractable, | 59 bool extractable, |
60 blink::WebCryptoKeyUsageMask usage_mask, | 60 blink::WebCryptoKeyUsageMask usage_mask, |
61 blink::WebCryptoKey* key) const OVERRIDE { | 61 blink::WebCryptoKey* key) const override { |
62 const blink::WebCryptoHmacKeyGenParams* params = | 62 const blink::WebCryptoHmacKeyGenParams* params = |
63 algorithm.hmacKeyGenParams(); | 63 algorithm.hmacKeyGenParams(); |
64 | 64 |
65 const blink::WebCryptoAlgorithm& hash = params->hash(); | 65 const blink::WebCryptoAlgorithm& hash = params->hash(); |
66 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; | 66 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
67 if (!WebCryptoHashToHMACMechanism(hash, &mechanism)) | 67 if (!WebCryptoHashToHMACMechanism(hash, &mechanism)) |
68 return Status::ErrorUnsupported(); | 68 return Status::ErrorUnsupported(); |
69 | 69 |
70 unsigned int keylen_bits = 0; | 70 unsigned int keylen_bits = 0; |
71 Status status = GetHmacKeyGenLengthInBits(params, &keylen_bits); | 71 Status status = GetHmacKeyGenLengthInBits(params, &keylen_bits); |
72 if (status.IsError()) | 72 if (status.IsError()) |
73 return status; | 73 return status; |
74 | 74 |
75 return GenerateSecretKeyNss( | 75 return GenerateSecretKeyNss( |
76 blink::WebCryptoKeyAlgorithm::createHmac(hash.id(), keylen_bits), | 76 blink::WebCryptoKeyAlgorithm::createHmac(hash.id(), keylen_bits), |
77 extractable, | 77 extractable, |
78 usage_mask, | 78 usage_mask, |
79 keylen_bits / 8, | 79 keylen_bits / 8, |
80 mechanism, | 80 mechanism, |
81 key); | 81 key); |
82 } | 82 } |
83 | 83 |
84 virtual Status VerifyKeyUsagesBeforeImportKey( | 84 virtual Status VerifyKeyUsagesBeforeImportKey( |
85 blink::WebCryptoKeyFormat format, | 85 blink::WebCryptoKeyFormat format, |
86 blink::WebCryptoKeyUsageMask usage_mask) const OVERRIDE { | 86 blink::WebCryptoKeyUsageMask usage_mask) const override { |
87 switch (format) { | 87 switch (format) { |
88 case blink::WebCryptoKeyFormatRaw: | 88 case blink::WebCryptoKeyFormatRaw: |
89 case blink::WebCryptoKeyFormatJwk: | 89 case blink::WebCryptoKeyFormatJwk: |
90 return CheckKeyCreationUsages(kAllKeyUsages, usage_mask); | 90 return CheckKeyCreationUsages(kAllKeyUsages, usage_mask); |
91 default: | 91 default: |
92 return Status::ErrorUnsupportedImportKeyFormat(); | 92 return Status::ErrorUnsupportedImportKeyFormat(); |
93 } | 93 } |
94 } | 94 } |
95 | 95 |
96 virtual Status VerifyKeyUsagesBeforeGenerateKey( | 96 virtual Status VerifyKeyUsagesBeforeGenerateKey( |
97 blink::WebCryptoKeyUsageMask usage_mask) const OVERRIDE { | 97 blink::WebCryptoKeyUsageMask usage_mask) const override { |
98 return CheckKeyCreationUsages(kAllKeyUsages, usage_mask); | 98 return CheckKeyCreationUsages(kAllKeyUsages, usage_mask); |
99 } | 99 } |
100 | 100 |
101 virtual Status ImportKeyRaw(const CryptoData& key_data, | 101 virtual Status ImportKeyRaw(const CryptoData& key_data, |
102 const blink::WebCryptoAlgorithm& algorithm, | 102 const blink::WebCryptoAlgorithm& algorithm, |
103 bool extractable, | 103 bool extractable, |
104 blink::WebCryptoKeyUsageMask usage_mask, | 104 blink::WebCryptoKeyUsageMask usage_mask, |
105 blink::WebCryptoKey* key) const OVERRIDE { | 105 blink::WebCryptoKey* key) const override { |
106 const blink::WebCryptoAlgorithm& hash = | 106 const blink::WebCryptoAlgorithm& hash = |
107 algorithm.hmacImportParams()->hash(); | 107 algorithm.hmacImportParams()->hash(); |
108 | 108 |
109 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; | 109 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
110 if (!WebCryptoHashToHMACMechanism(hash, &mechanism)) | 110 if (!WebCryptoHashToHMACMechanism(hash, &mechanism)) |
111 return Status::ErrorUnsupported(); | 111 return Status::ErrorUnsupported(); |
112 | 112 |
113 base::CheckedNumeric<unsigned int> keylen_bits(key_data.byte_length()); | 113 base::CheckedNumeric<unsigned int> keylen_bits(key_data.byte_length()); |
114 keylen_bits *= 8; | 114 keylen_bits *= 8; |
115 | 115 |
116 if (!keylen_bits.IsValid()) | 116 if (!keylen_bits.IsValid()) |
117 return Status::ErrorDataTooLarge(); | 117 return Status::ErrorDataTooLarge(); |
118 | 118 |
119 return ImportKeyRawNss(key_data, | 119 return ImportKeyRawNss(key_data, |
120 blink::WebCryptoKeyAlgorithm::createHmac( | 120 blink::WebCryptoKeyAlgorithm::createHmac( |
121 hash.id(), keylen_bits.ValueOrDie()), | 121 hash.id(), keylen_bits.ValueOrDie()), |
122 extractable, | 122 extractable, |
123 usage_mask, | 123 usage_mask, |
124 mechanism, | 124 mechanism, |
125 CKF_SIGN | CKF_VERIFY, | 125 CKF_SIGN | CKF_VERIFY, |
126 key); | 126 key); |
127 } | 127 } |
128 | 128 |
129 virtual Status ImportKeyJwk(const CryptoData& key_data, | 129 virtual Status ImportKeyJwk(const CryptoData& key_data, |
130 const blink::WebCryptoAlgorithm& algorithm, | 130 const blink::WebCryptoAlgorithm& algorithm, |
131 bool extractable, | 131 bool extractable, |
132 blink::WebCryptoKeyUsageMask usage_mask, | 132 blink::WebCryptoKeyUsageMask usage_mask, |
133 blink::WebCryptoKey* key) const OVERRIDE { | 133 blink::WebCryptoKey* key) const override { |
134 const char* algorithm_name = | 134 const char* algorithm_name = |
135 GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id()); | 135 GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id()); |
136 if (!algorithm_name) | 136 if (!algorithm_name) |
137 return Status::ErrorUnexpected(); | 137 return Status::ErrorUnexpected(); |
138 | 138 |
139 std::vector<uint8_t> raw_data; | 139 std::vector<uint8_t> raw_data; |
140 Status status = ReadSecretKeyJwk( | 140 Status status = ReadSecretKeyJwk( |
141 key_data, algorithm_name, extractable, usage_mask, &raw_data); | 141 key_data, algorithm_name, extractable, usage_mask, &raw_data); |
142 if (status.IsError()) | 142 if (status.IsError()) |
143 return status; | 143 return status; |
144 | 144 |
145 return ImportKeyRaw( | 145 return ImportKeyRaw( |
146 CryptoData(raw_data), algorithm, extractable, usage_mask, key); | 146 CryptoData(raw_data), algorithm, extractable, usage_mask, key); |
147 } | 147 } |
148 | 148 |
149 virtual Status ExportKeyRaw(const blink::WebCryptoKey& key, | 149 virtual Status ExportKeyRaw(const blink::WebCryptoKey& key, |
150 std::vector<uint8_t>* buffer) const OVERRIDE { | 150 std::vector<uint8_t>* buffer) const override { |
151 *buffer = SymKeyNss::Cast(key)->raw_key_data(); | 151 *buffer = SymKeyNss::Cast(key)->raw_key_data(); |
152 return Status::Success(); | 152 return Status::Success(); |
153 } | 153 } |
154 | 154 |
155 virtual Status ExportKeyJwk(const blink::WebCryptoKey& key, | 155 virtual Status ExportKeyJwk(const blink::WebCryptoKey& key, |
156 std::vector<uint8_t>* buffer) const OVERRIDE { | 156 std::vector<uint8_t>* buffer) const override { |
157 SymKeyNss* sym_key = SymKeyNss::Cast(key); | 157 SymKeyNss* sym_key = SymKeyNss::Cast(key); |
158 const std::vector<uint8_t>& raw_data = sym_key->raw_key_data(); | 158 const std::vector<uint8_t>& raw_data = sym_key->raw_key_data(); |
159 | 159 |
160 const char* algorithm_name = | 160 const char* algorithm_name = |
161 GetJwkHmacAlgorithmName(key.algorithm().hmacParams()->hash().id()); | 161 GetJwkHmacAlgorithmName(key.algorithm().hmacParams()->hash().id()); |
162 if (!algorithm_name) | 162 if (!algorithm_name) |
163 return Status::ErrorUnexpected(); | 163 return Status::ErrorUnexpected(); |
164 | 164 |
165 WriteSecretKeyJwk(CryptoData(raw_data), | 165 WriteSecretKeyJwk(CryptoData(raw_data), |
166 algorithm_name, | 166 algorithm_name, |
167 key.extractable(), | 167 key.extractable(), |
168 key.usages(), | 168 key.usages(), |
169 buffer); | 169 buffer); |
170 | 170 |
171 return Status::Success(); | 171 return Status::Success(); |
172 } | 172 } |
173 | 173 |
174 virtual Status Sign(const blink::WebCryptoAlgorithm& algorithm, | 174 virtual Status Sign(const blink::WebCryptoAlgorithm& algorithm, |
175 const blink::WebCryptoKey& key, | 175 const blink::WebCryptoKey& key, |
176 const CryptoData& data, | 176 const CryptoData& data, |
177 std::vector<uint8_t>* buffer) const OVERRIDE { | 177 std::vector<uint8_t>* buffer) const override { |
178 const blink::WebCryptoAlgorithm& hash = | 178 const blink::WebCryptoAlgorithm& hash = |
179 key.algorithm().hmacParams()->hash(); | 179 key.algorithm().hmacParams()->hash(); |
180 PK11SymKey* sym_key = SymKeyNss::Cast(key)->key(); | 180 PK11SymKey* sym_key = SymKeyNss::Cast(key)->key(); |
181 | 181 |
182 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; | 182 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
183 if (!WebCryptoHashToHMACMechanism(hash, &mechanism)) | 183 if (!WebCryptoHashToHMACMechanism(hash, &mechanism)) |
184 return Status::ErrorUnexpected(); | 184 return Status::ErrorUnexpected(); |
185 | 185 |
186 SECItem param_item = {siBuffer, NULL, 0}; | 186 SECItem param_item = {siBuffer, NULL, 0}; |
187 SECItem data_item = MakeSECItemForBuffer(data); | 187 SECItem data_item = MakeSECItemForBuffer(data); |
(...skipping 18 matching lines...) Expand all Loading... |
206 } | 206 } |
207 | 207 |
208 CHECK_EQ(buffer->size(), signature_item.len); | 208 CHECK_EQ(buffer->size(), signature_item.len); |
209 return Status::Success(); | 209 return Status::Success(); |
210 } | 210 } |
211 | 211 |
212 virtual Status Verify(const blink::WebCryptoAlgorithm& algorithm, | 212 virtual Status Verify(const blink::WebCryptoAlgorithm& algorithm, |
213 const blink::WebCryptoKey& key, | 213 const blink::WebCryptoKey& key, |
214 const CryptoData& signature, | 214 const CryptoData& signature, |
215 const CryptoData& data, | 215 const CryptoData& data, |
216 bool* signature_match) const OVERRIDE { | 216 bool* signature_match) const override { |
217 std::vector<uint8_t> result; | 217 std::vector<uint8_t> result; |
218 Status status = Sign(algorithm, key, data, &result); | 218 Status status = Sign(algorithm, key, data, &result); |
219 | 219 |
220 if (status.IsError()) | 220 if (status.IsError()) |
221 return status; | 221 return status; |
222 | 222 |
223 // Do not allow verification of truncated MACs. | 223 // Do not allow verification of truncated MACs. |
224 *signature_match = result.size() == signature.byte_length() && | 224 *signature_match = result.size() == signature.byte_length() && |
225 crypto::SecureMemEqual(vector_as_array(&result), | 225 crypto::SecureMemEqual(vector_as_array(&result), |
226 signature.bytes(), | 226 signature.bytes(), |
227 signature.byte_length()); | 227 signature.byte_length()); |
228 | 228 |
229 return Status::Success(); | 229 return Status::Success(); |
230 } | 230 } |
231 }; | 231 }; |
232 | 232 |
233 } // namespace | 233 } // namespace |
234 | 234 |
235 AlgorithmImplementation* CreatePlatformHmacImplementation() { | 235 AlgorithmImplementation* CreatePlatformHmacImplementation() { |
236 return new HmacImplementation; | 236 return new HmacImplementation; |
237 } | 237 } |
238 | 238 |
239 } // namespace webcrypto | 239 } // namespace webcrypto |
240 | 240 |
241 } // namespace content | 241 } // namespace content |
OLD | NEW |