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 "CryptoAlgorithmAesCbcParams.h"
32 #include "CryptoAlgorithmAesCbcParamsDeprecated.h"
33 #include "CryptoAlgorithmAesKeyGenParams.h"
34 #include "CryptoAlgorithmAesKeyGenParamsDeprecated.h"
35 #include "CryptoKeyAES.h"
36 #include "CryptoKeyDataOctetSequence.h"
37 #include "ExceptionCode.h"
41 static const char* const ALG128 = "A128CBC";
42 static const char* const ALG192 = "A192CBC";
43 static const char* const ALG256 = "A256CBC";
44 static const size_t IVSIZE = 16;
46 static inline bool usagesAreInvalidForCryptoAlgorithmAES_CBC(CryptoKeyUsageBitmap usages)
48 return usages & (CryptoKeyUsageSign | CryptoKeyUsageVerify | CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits);
51 Ref<CryptoAlgorithm> CryptoAlgorithmAES_CBC::create()
53 return adoptRef(*new CryptoAlgorithmAES_CBC);
56 CryptoAlgorithmIdentifier CryptoAlgorithmAES_CBC::identifier() const
61 bool CryptoAlgorithmAES_CBC::keyAlgorithmMatches(const CryptoAlgorithmAesCbcParamsDeprecated&, const CryptoKey& key) const
63 if (key.algorithmIdentifier() != s_identifier)
65 ASSERT(is<CryptoKeyAES>(key));
69 void CryptoAlgorithmAES_CBC::encrypt(std::unique_ptr<CryptoAlgorithmParameters>&& parameters, Ref<CryptoKey>&& key, Vector<uint8_t>&& plainText, VectorCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, WorkQueue& workQueue)
72 auto& aesParameters = downcast<CryptoAlgorithmAesCbcParams>(*parameters);
73 if (aesParameters.ivVector().size() != IVSIZE) {
74 exceptionCallback(OperationError);
77 platformEncrypt(WTFMove(parameters), WTFMove(key), WTFMove(plainText), WTFMove(callback), WTFMove(exceptionCallback), context, workQueue);
80 void CryptoAlgorithmAES_CBC::generateKey(const std::unique_ptr<CryptoAlgorithmParameters>&& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, ExceptionCallback&& exceptionCallback, ScriptExecutionContext&)
83 auto& aesParameters = downcast<CryptoAlgorithmAesKeyGenParams>(*parameters);
85 if (usagesAreInvalidForCryptoAlgorithmAES_CBC(usages)) {
86 exceptionCallback(SYNTAX_ERR);
90 auto result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_CBC, aesParameters.length, extractable, usages);
92 exceptionCallback(OperationError);
96 callback(result.get(), nullptr);
99 void CryptoAlgorithmAES_CBC::importKey(SubtleCrypto::KeyFormat format, KeyData&& data, const std::unique_ptr<CryptoAlgorithmParameters>&& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyCallback&& callback, ExceptionCallback&& exceptionCallback)
102 if (usagesAreInvalidForCryptoAlgorithmAES_CBC(usages)) {
103 exceptionCallback(SYNTAX_ERR);
107 RefPtr<CryptoKeyAES> result;
109 case SubtleCrypto::KeyFormat::Raw:
110 result = CryptoKeyAES::importRaw(parameters->identifier, WTFMove(WTF::get<Vector<uint8_t>>(data)), extractable, usages);
112 case SubtleCrypto::KeyFormat::Jwk: {
113 auto checkAlgCallback = [](size_t length, const Optional<String>& alg) -> bool {
115 case CryptoKeyAES::s_length128:
116 return !alg || alg.value() == ALG128;
117 case CryptoKeyAES::s_length192:
118 return !alg || alg.value() == ALG192;
119 case CryptoKeyAES::s_length256:
120 return !alg || alg.value() == ALG256;
124 result = CryptoKeyAES::importJwk(parameters->identifier, WTFMove(WTF::get<JsonWebKey>(data)), extractable, usages, WTFMove(checkAlgCallback));
128 exceptionCallback(NOT_SUPPORTED_ERR);
132 exceptionCallback(DataError);
139 void CryptoAlgorithmAES_CBC::exportKey(SubtleCrypto::KeyFormat format, Ref<CryptoKey>&& key, KeyDataCallback&& callback, ExceptionCallback&& exceptionCallback)
141 const auto& aesKey = downcast<CryptoKeyAES>(key.get());
143 if (aesKey.key().isEmpty()) {
144 exceptionCallback(OperationError);
150 case SubtleCrypto::KeyFormat::Raw:
151 result = Vector<uint8_t>(aesKey.key());
153 case SubtleCrypto::KeyFormat::Jwk: {
154 JsonWebKey jwk = aesKey.exportJwk();
155 switch (aesKey.key().size() * 8) {
156 case CryptoKeyAES::s_length128:
157 jwk.alg = String(ALG128);
159 case CryptoKeyAES::s_length192:
160 jwk.alg = String(ALG192);
162 case CryptoKeyAES::s_length256:
163 jwk.alg = String(ALG256);
166 ASSERT_NOT_REACHED();
168 result = WTFMove(jwk);
172 exceptionCallback(NOT_SUPPORTED_ERR);
176 callback(format, WTFMove(result));
179 ExceptionOr<void> CryptoAlgorithmAES_CBC::encrypt(const CryptoAlgorithmParametersDeprecated& parameters, const CryptoKey& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback)
181 auto& aesCBCParameters = downcast<CryptoAlgorithmAesCbcParamsDeprecated>(parameters);
182 if (!keyAlgorithmMatches(aesCBCParameters, key))
183 return Exception { NOT_SUPPORTED_ERR };
184 return platformEncrypt(aesCBCParameters, downcast<CryptoKeyAES>(key), data, WTFMove(callback), WTFMove(failureCallback));
187 ExceptionOr<void> CryptoAlgorithmAES_CBC::decrypt(const CryptoAlgorithmParametersDeprecated& parameters, const CryptoKey& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback)
189 auto& aesCBCParameters = downcast<CryptoAlgorithmAesCbcParamsDeprecated>(parameters);
190 if (!keyAlgorithmMatches(aesCBCParameters, key))
191 return Exception { NOT_SUPPORTED_ERR };
192 return platformDecrypt(aesCBCParameters, downcast<CryptoKeyAES>(key), data, WTFMove(callback), WTFMove(failureCallback));
195 ExceptionOr<void> CryptoAlgorithmAES_CBC::generateKey(const CryptoAlgorithmParametersDeprecated& parameters, bool extractable, CryptoKeyUsageBitmap usages, KeyOrKeyPairCallback&& callback, VoidCallback&& failureCallback, ScriptExecutionContext&)
197 auto& aesParameters = downcast<CryptoAlgorithmAesKeyGenParamsDeprecated>(parameters);
199 auto result = CryptoKeyAES::generate(CryptoAlgorithmIdentifier::AES_CBC, aesParameters.length, extractable, usages);
205 callback(result.get(), nullptr);
209 ExceptionOr<void> CryptoAlgorithmAES_CBC::importKey(const CryptoAlgorithmParametersDeprecated&, const CryptoKeyData& keyData, bool extractable, CryptoKeyUsageBitmap usage, KeyCallback&& callback, VoidCallback&&)
211 if (!is<CryptoKeyDataOctetSequence>(keyData))
212 return Exception { NOT_SUPPORTED_ERR };
213 auto& keyDataOctetSequence = downcast<CryptoKeyDataOctetSequence>(keyData);
214 callback(CryptoKeyAES::create(CryptoAlgorithmIdentifier::AES_CBC, keyDataOctetSequence.octetSequence(), extractable, usage));
220 #endif // ENABLE(SUBTLE_CRYPTO)