2 * Copyright (C) 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #include "CryptoAlgorithmAES_CBC.h"
29 #if ENABLE(SUBTLE_CRYPTO)
31 #include "CryptoAlgorithmAesCbcParamsDeprecated.h"
32 #include "CryptoAlgorithmAesKeyGenParams.h"
33 #include "CryptoAlgorithmAesKeyGenParamsDeprecated.h"
34 #include "CryptoKeyAES.h"
35 #include "CryptoKeyDataOctetSequence.h"
36 #include "ExceptionCode.h"
40 static const char* const ALG128 = "A128CBC";
41 static const char* const ALG192 = "A192CBC";
42 static const char* const ALG256 = "A256CBC";
44 static inline bool usagesAreInvalidForCryptoAlgorithmAES_CBC(CryptoKeyUsageBitmap usages)
46 return usages & (CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits);
49 Ref<CryptoAlgorithm> CryptoAlgorithmAES_CBC::create()
51 return adoptRef(*new CryptoAlgorithmAES_CBC);
54 CryptoAlgorithmIdentifier CryptoAlgorithmAES_CBC::identifier() const
59 bool CryptoAlgorithmAES_CBC::keyAlgorithmMatches(const CryptoAlgorithmAesCbcParamsDeprecated&, const CryptoKey& key) const
61 if (key.algorithmIdentifier() != s_identifier)
63 ASSERT(is<CryptoKeyAES>(key));
67 void CryptoAlgorithmAES_CBC::generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
69 auto& aesParameters = downcast<CryptoAlgorithmAesKeyGenParams>(*parameters);
71 if (usagesAreInvalidForCryptoAlgorithmAES_CBC(usages)) {
72 exceptionCallback(SYNTAX_ERR);
76 auto result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_CBC, aesParameters.length, extractable, usages);
78 exceptionCallback(OperationError);
82 callback(result.get(), nullptr);
85 void CryptoAlgorithmAES_CBC::importKey(SubtleCrypto::KeyFormat format, KeyData&& data, const std::unique_ptr<CryptoAlgorithmParameters>&& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
87 if (usagesAreInvalidForCryptoAlgorithmAES_CBC(usages)) {
88 exceptionCallback(SYNTAX_ERR);
92 RefPtr<CryptoKeyAES> result;
94 case SubtleCrypto::KeyFormat::Raw:
95 result = CryptoKeyAES::importRaw(parameters->identifier, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages);
97 case SubtleCrypto::KeyFormat::Jwk: {
98 auto checkAlgCallback = [](size_t length, const Optional<String>& alg) -> bool {
100 case CryptoKeyAES::s_length128:
101 return !alg || alg.value() == ALG128;
102 case CryptoKeyAES::s_length192:
103 return !alg || alg.value() == ALG192;
104 case CryptoKeyAES::s_length256:
105 return !alg || alg.value() == ALG256;
109 result = CryptoKeyAES::importJwk(parameters->identifier, WTFMove(WTF::get<JsonWebKey>(data)), extractable, usages, WTFMove(checkAlgCallback));
113 exceptionCallback(NOT_SUPPORTED_ERR);
117 exceptionCallback(DataError);
124 void CryptoAlgorithmAES_CBC::exportKey(SubtleCrypto::KeyFormat format, RefPtr<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
126 const auto& aesKey = downcast<CryptoKeyAES>(*key);
128 if (aesKey.key().isEmpty()) {
129 exceptionCallback(OperationError);
135 case SubtleCrypto::KeyFormat::Raw:
136 result = Vector<uint8_t>(aesKey.key());
138 case SubtleCrypto::KeyFormat::Jwk: {
139 JsonWebKey jwk = aesKey.exportJwk();
140 switch (aesKey.key().size() * 8) {
141 case CryptoKeyAES::s_length128:
142 jwk.alg = String(ALG128);
144 case CryptoKeyAES::s_length192:
145 jwk.alg = String(ALG192);
147 case CryptoKeyAES::s_length256:
148 jwk.alg = String(ALG256);
151 ASSERT_NOT_REACHED();
153 result = WTFMove(jwk);
157 exceptionCallback(NOT_SUPPORTED_ERR);
161 callback(format, WTFMove(result));
164 ExceptionOr<void> CryptoAlgorithmAES_CBC::encrypt(const CryptoAlgorithmParametersDeprecated& parameters, const CryptoKey& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback)
166 auto& aesCBCParameters = downcast<CryptoAlgorithmAesCbcParamsDeprecated>(parameters);
167 if (!keyAlgorithmMatches(aesCBCParameters, key))
168 return Exception { NOT_SUPPORTED_ERR };
169 return platformEncrypt(aesCBCParameters, downcast<CryptoKeyAES>(key), data, WTFMove(callback), WTFMove(failureCallback));
172 ExceptionOr<void> CryptoAlgorithmAES_CBC::decrypt(const CryptoAlgorithmParametersDeprecated& parameters, const CryptoKey& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback)
174 auto& aesCBCParameters = downcast<CryptoAlgorithmAesCbcParamsDeprecated>(parameters);
175 if (!keyAlgorithmMatches(aesCBCParameters, key))
176 return Exception { NOT_SUPPORTED_ERR };
177 return platformDecrypt(aesCBCParameters, downcast<CryptoKeyAES>(key), data, WTFMove(callback), WTFMove(failureCallback));
180 ExceptionOr<void> CryptoAlgorithmAES_CBC::generateKey(const CryptoAlgorithmParametersDeprecated& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, VoidCallback&& failureCallback, ScriptExecutionContext&)
182 auto& aesParameters = downcast<CryptoAlgorithmAesKeyGenParamsDeprecated>(parameters);
184 auto result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_CBC, aesParameters.length, extractable, usages);
190 callback(result.get(), nullptr);
194 ExceptionOr<void> CryptoAlgorithmAES_CBC::importKey(const CryptoAlgorithmParametersDeprecated&, const CryptoKeyData& keyData, bool extractable, CryptoKeyUsageBitmap usage, KeyCallback&& callback, VoidCallback&&)
196 if (!is<CryptoKeyDataOctetSequence>(keyData))
197 return Exception { NOT_SUPPORTED_ERR };
198 auto& keyDataOctetSequence = downcast<CryptoKeyDataOctetSequence>(keyData);
199 callback(CryptoKeyAES::create(CryptoAlgorithmIdentifier::AES_CBC, keyDataOctetSequence.octetSequence(), extractable, usage));
205 #endif // ENABLE(SUBTLE_CRYPTO)