| 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 <openssl/hmac.h> | 5 #include <openssl/hmac.h> |
| 6 #include <stddef.h> | 6 #include <stddef.h> |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 } | 111 } |
| 112 | 112 |
| 113 class HmacImplementation : public AlgorithmImplementation { | 113 class HmacImplementation : public AlgorithmImplementation { |
| 114 public: | 114 public: |
| 115 HmacImplementation() {} | 115 HmacImplementation() {} |
| 116 | 116 |
| 117 Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm, | 117 Status GenerateKey(const blink::WebCryptoAlgorithm& algorithm, |
| 118 bool extractable, | 118 bool extractable, |
| 119 blink::WebCryptoKeyUsageMask usages, | 119 blink::WebCryptoKeyUsageMask usages, |
| 120 GenerateKeyResult* result) const override { | 120 GenerateKeyResult* result) const override { |
| 121 Status status = CheckSecretKeyCreationUsages(kAllKeyUsages, usages); | 121 Status status = CheckKeyCreationUsages(kAllKeyUsages, usages); |
| 122 if (status.IsError()) | 122 if (status.IsError()) |
| 123 return status; | 123 return status; |
| 124 | 124 |
| 125 const blink::WebCryptoHmacKeyGenParams* params = | 125 const blink::WebCryptoHmacKeyGenParams* params = |
| 126 algorithm.hmacKeyGenParams(); | 126 algorithm.hmacKeyGenParams(); |
| 127 | 127 |
| 128 unsigned int keylen_bits = 0; | 128 unsigned int keylen_bits = 0; |
| 129 if (params->hasLengthBits()) { | 129 if (params->hasLengthBits()) { |
| 130 keylen_bits = params->optionalLengthBits(); | 130 keylen_bits = params->optionalLengthBits(); |
| 131 // Zero-length HMAC keys are disallowed by the spec. | 131 // Zero-length HMAC keys are disallowed by the spec. |
| 132 if (keylen_bits == 0) | 132 if (keylen_bits == 0) |
| 133 return Status::ErrorGenerateHmacKeyLengthZero(); | 133 return Status::ErrorGenerateHmacKeyLengthZero(); |
| 134 } else { | 134 } else { |
| 135 status = GetDigestBlockSizeBits(params->hash(), &keylen_bits); | 135 status = GetDigestBlockSizeBits(params->hash(), &keylen_bits); |
| 136 if (status.IsError()) | 136 if (status.IsError()) |
| 137 return status; | 137 return status; |
| 138 } | 138 } |
| 139 | 139 |
| 140 return GenerateWebCryptoSecretKey(blink::WebCryptoKeyAlgorithm::createHmac( | 140 return GenerateWebCryptoSecretKey(blink::WebCryptoKeyAlgorithm::createHmac( |
| 141 params->hash().id(), keylen_bits), | 141 params->hash().id(), keylen_bits), |
| 142 extractable, usages, keylen_bits, result); | 142 extractable, usages, keylen_bits, result); |
| 143 } | 143 } |
| 144 | 144 |
| 145 Status VerifyKeyUsagesBeforeImportKey( | 145 Status ImportKey(blink::WebCryptoKeyFormat format, |
| 146 blink::WebCryptoKeyFormat format, | 146 const CryptoData& key_data, |
| 147 blink::WebCryptoKeyUsageMask usages) const override { | 147 const blink::WebCryptoAlgorithm& algorithm, |
| 148 bool extractable, |
| 149 blink::WebCryptoKeyUsageMask usages, |
| 150 blink::WebCryptoKey* key) const override { |
| 148 switch (format) { | 151 switch (format) { |
| 149 case blink::WebCryptoKeyFormatRaw: | 152 case blink::WebCryptoKeyFormatRaw: |
| 153 return ImportKeyRaw(key_data, algorithm, extractable, usages, key); |
| 150 case blink::WebCryptoKeyFormatJwk: | 154 case blink::WebCryptoKeyFormatJwk: |
| 151 return CheckSecretKeyCreationUsages(kAllKeyUsages, usages); | 155 return ImportKeyJwk(key_data, algorithm, extractable, usages, key); |
| 152 default: | 156 default: |
| 153 return Status::ErrorUnsupportedImportKeyFormat(); | 157 return Status::ErrorUnsupportedImportKeyFormat(); |
| 154 } | 158 } |
| 155 } | 159 } |
| 156 | 160 |
| 161 Status ExportKey(blink::WebCryptoKeyFormat format, |
| 162 const blink::WebCryptoKey& key, |
| 163 std::vector<uint8_t>* buffer) const override { |
| 164 switch (format) { |
| 165 case blink::WebCryptoKeyFormatRaw: |
| 166 return ExportKeyRaw(key, buffer); |
| 167 case blink::WebCryptoKeyFormatJwk: |
| 168 return ExportKeyJwk(key, buffer); |
| 169 default: |
| 170 return Status::ErrorUnsupportedExportKeyFormat(); |
| 171 } |
| 172 } |
| 173 |
| 157 Status ImportKeyRaw(const CryptoData& key_data, | 174 Status ImportKeyRaw(const CryptoData& key_data, |
| 158 const blink::WebCryptoAlgorithm& algorithm, | 175 const blink::WebCryptoAlgorithm& algorithm, |
| 159 bool extractable, | 176 bool extractable, |
| 160 blink::WebCryptoKeyUsageMask usages, | 177 blink::WebCryptoKeyUsageMask usages, |
| 161 blink::WebCryptoKey* key) const override { | 178 blink::WebCryptoKey* key) const { |
| 179 Status status = CheckKeyCreationUsages(kAllKeyUsages, usages); |
| 180 if (status.IsError()) |
| 181 return status; |
| 182 |
| 162 const blink::WebCryptoHmacImportParams* params = | 183 const blink::WebCryptoHmacImportParams* params = |
| 163 algorithm.hmacImportParams(); | 184 algorithm.hmacImportParams(); |
| 164 | 185 |
| 165 unsigned int keylen_bits = 0; | 186 unsigned int keylen_bits = 0; |
| 166 Status status = GetHmacImportKeyLengthBits(params, key_data.byte_length(), | 187 status = GetHmacImportKeyLengthBits(params, key_data.byte_length(), |
| 167 &keylen_bits); | 188 &keylen_bits); |
| 168 if (status.IsError()) | 189 if (status.IsError()) |
| 169 return status; | 190 return status; |
| 170 | 191 |
| 171 const blink::WebCryptoKeyAlgorithm key_algorithm = | 192 const blink::WebCryptoKeyAlgorithm key_algorithm = |
| 172 blink::WebCryptoKeyAlgorithm::createHmac(params->hash().id(), | 193 blink::WebCryptoKeyAlgorithm::createHmac(params->hash().id(), |
| 173 keylen_bits); | 194 keylen_bits); |
| 174 | 195 |
| 175 // If no bit truncation was requested, then done! | 196 // If no bit truncation was requested, then done! |
| 176 if ((keylen_bits % 8) == 0) { | 197 if ((keylen_bits % 8) == 0) { |
| 177 return CreateWebCryptoSecretKey(key_data, key_algorithm, extractable, | 198 return CreateWebCryptoSecretKey(key_data, key_algorithm, extractable, |
| 178 usages, key); | 199 usages, key); |
| 179 } | 200 } |
| 180 | 201 |
| 181 // Otherwise zero out the unused bits in the key data before importing. | 202 // Otherwise zero out the unused bits in the key data before importing. |
| 182 std::vector<uint8_t> modified_key_data( | 203 std::vector<uint8_t> modified_key_data( |
| 183 key_data.bytes(), key_data.bytes() + key_data.byte_length()); | 204 key_data.bytes(), key_data.bytes() + key_data.byte_length()); |
| 184 TruncateToBitLength(keylen_bits, &modified_key_data); | 205 TruncateToBitLength(keylen_bits, &modified_key_data); |
| 185 return CreateWebCryptoSecretKey(CryptoData(modified_key_data), | 206 return CreateWebCryptoSecretKey(CryptoData(modified_key_data), |
| 186 key_algorithm, extractable, usages, key); | 207 key_algorithm, extractable, usages, key); |
| 187 } | 208 } |
| 188 | 209 |
| 189 Status ImportKeyJwk(const CryptoData& key_data, | 210 Status ImportKeyJwk(const CryptoData& key_data, |
| 190 const blink::WebCryptoAlgorithm& algorithm, | 211 const blink::WebCryptoAlgorithm& algorithm, |
| 191 bool extractable, | 212 bool extractable, |
| 192 blink::WebCryptoKeyUsageMask usages, | 213 blink::WebCryptoKeyUsageMask usages, |
| 193 blink::WebCryptoKey* key) const override { | 214 blink::WebCryptoKey* key) const { |
| 215 Status status = CheckKeyCreationUsages(kAllKeyUsages, usages); |
| 216 if (status.IsError()) |
| 217 return status; |
| 218 |
| 194 const char* algorithm_name = | 219 const char* algorithm_name = |
| 195 GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id()); | 220 GetJwkHmacAlgorithmName(algorithm.hmacImportParams()->hash().id()); |
| 196 if (!algorithm_name) | 221 if (!algorithm_name) |
| 197 return Status::ErrorUnexpected(); | 222 return Status::ErrorUnexpected(); |
| 198 | 223 |
| 199 std::vector<uint8_t> raw_data; | 224 std::vector<uint8_t> raw_data; |
| 200 JwkReader jwk; | 225 JwkReader jwk; |
| 201 Status status = ReadSecretKeyNoExpectedAlgJwk(key_data, extractable, usages, | 226 status = ReadSecretKeyNoExpectedAlgJwk(key_data, extractable, usages, |
| 202 &raw_data, &jwk); | 227 &raw_data, &jwk); |
| 203 if (status.IsError()) | 228 if (status.IsError()) |
| 204 return status; | 229 return status; |
| 205 status = jwk.VerifyAlg(algorithm_name); | 230 status = jwk.VerifyAlg(algorithm_name); |
| 206 if (status.IsError()) | 231 if (status.IsError()) |
| 207 return status; | 232 return status; |
| 208 | 233 |
| 209 return ImportKeyRaw(CryptoData(raw_data), algorithm, extractable, usages, | 234 return ImportKeyRaw(CryptoData(raw_data), algorithm, extractable, usages, |
| 210 key); | 235 key); |
| 211 } | 236 } |
| 212 | 237 |
| 213 Status ExportKeyRaw(const blink::WebCryptoKey& key, | 238 Status ExportKeyRaw(const blink::WebCryptoKey& key, |
| 214 std::vector<uint8_t>* buffer) const override { | 239 std::vector<uint8_t>* buffer) const { |
| 215 *buffer = GetSymmetricKeyData(key); | 240 *buffer = GetSymmetricKeyData(key); |
| 216 return Status::Success(); | 241 return Status::Success(); |
| 217 } | 242 } |
| 218 | 243 |
| 219 Status ExportKeyJwk(const blink::WebCryptoKey& key, | 244 Status ExportKeyJwk(const blink::WebCryptoKey& key, |
| 220 std::vector<uint8_t>* buffer) const override { | 245 std::vector<uint8_t>* buffer) const { |
| 221 const std::vector<uint8_t>& raw_data = GetSymmetricKeyData(key); | 246 const std::vector<uint8_t>& raw_data = GetSymmetricKeyData(key); |
| 222 | 247 |
| 223 const char* algorithm_name = | 248 const char* algorithm_name = |
| 224 GetJwkHmacAlgorithmName(key.algorithm().hmacParams()->hash().id()); | 249 GetJwkHmacAlgorithmName(key.algorithm().hmacParams()->hash().id()); |
| 225 if (!algorithm_name) | 250 if (!algorithm_name) |
| 226 return Status::ErrorUnexpected(); | 251 return Status::ErrorUnexpected(); |
| 227 | 252 |
| 228 WriteSecretKeyJwk(CryptoData(raw_data), algorithm_name, key.extractable(), | 253 WriteSecretKeyJwk(CryptoData(raw_data), algorithm_name, key.extractable(), |
| 229 key.usages(), buffer); | 254 key.usages(), buffer); |
| 230 | 255 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 } | 313 } |
| 289 }; | 314 }; |
| 290 | 315 |
| 291 } // namespace | 316 } // namespace |
| 292 | 317 |
| 293 std::unique_ptr<AlgorithmImplementation> CreateHmacImplementation() { | 318 std::unique_ptr<AlgorithmImplementation> CreateHmacImplementation() { |
| 294 return base::WrapUnique(new HmacImplementation); | 319 return base::WrapUnique(new HmacImplementation); |
| 295 } | 320 } |
| 296 | 321 |
| 297 } // namespace webcrypto | 322 } // namespace webcrypto |
| OLD | NEW |