77#include " CCMCipher.hpp"
88#include " HybridCipherFactorySpec.hpp"
99#include " OCBCipher.hpp"
10+ #include " Utils.hpp"
11+ #include " XSalsa20Cipher.hpp"
1012
1113namespace margelo ::nitro::crypto {
1214
@@ -20,40 +22,54 @@ class HybridCipherFactory : public HybridCipherFactorySpec {
2022 public:
2123 // Factory method exposed to JS
2224 inline std::shared_ptr<HybridCipherSpec> createCipher (const CipherArgs& args) {
23- // Create a temporary cipher context to determine the mode
24- EVP_CIPHER* cipher = EVP_CIPHER_fetch (nullptr , args.cipherType .c_str (), nullptr );
25- if (!cipher) {
26- throw std::runtime_error (" Invalid cipher type: " + args.cipherType );
27- }
28-
29- int mode = EVP_CIPHER_get_mode (cipher);
30- EVP_CIPHER_free (cipher);
3125
3226 // Create the appropriate cipher instance based on mode
3327 std::shared_ptr<HybridCipher> cipherInstance;
34- switch (mode) {
35- case EVP_CIPH_OCB_MODE: {
36- cipherInstance = std::make_shared<OCBCipher>();
37- cipherInstance->setArgs (args);
38- // Pass tag length (default 16 if not present)
39- size_t tag_len = args.authTagLen .has_value () ? static_cast <size_t >(args.authTagLen .value ()) : 16 ;
40- std::static_pointer_cast<OCBCipher>(cipherInstance)->init (args.cipherKey , args.iv , tag_len);
41- return cipherInstance;
42- }
43- case EVP_CIPH_CCM_MODE: {
44- cipherInstance = std::make_shared<CCMCipher>();
45- cipherInstance->setArgs (args);
46- cipherInstance->init (args.cipherKey , args.iv );
47- return cipherInstance;
48- }
49- default : {
50- cipherInstance = std::make_shared<HybridCipher>();
51- cipherInstance->setArgs (args);
52- cipherInstance->init (args.cipherKey , args.iv );
53- return cipherInstance;
28+
29+ // OpenSSL
30+ // temporary cipher context to determine the mode
31+ EVP_CIPHER* cipher = EVP_CIPHER_fetch (nullptr , args.cipherType .c_str (), nullptr );
32+ if (cipher) {
33+ int mode = EVP_CIPHER_get_mode (cipher);
34+
35+ switch (mode) {
36+ case EVP_CIPH_OCB_MODE: {
37+ cipherInstance = std::make_shared<OCBCipher>();
38+ cipherInstance->setArgs (args);
39+ // Pass tag length (default 16 if not present)
40+ size_t tag_len = args.authTagLen .has_value () ? static_cast <size_t >(args.authTagLen .value ()) : 16 ;
41+ std::static_pointer_cast<OCBCipher>(cipherInstance)->init (args.cipherKey , args.iv , tag_len);
42+ return cipherInstance;
43+ }
44+ case EVP_CIPH_CCM_MODE: {
45+ cipherInstance = std::make_shared<CCMCipher>();
46+ cipherInstance->setArgs (args);
47+ cipherInstance->init (args.cipherKey , args.iv );
48+ return cipherInstance;
49+ }
50+ default : {
51+ cipherInstance = std::make_shared<HybridCipher>();
52+ cipherInstance->setArgs (args);
53+ cipherInstance->init (args.cipherKey , args.iv );
54+ return cipherInstance;
55+ }
5456 }
5557 }
56- }
58+ EVP_CIPHER_free (cipher);
59+
60+ // libsodium
61+ std::string cipherName = toLower (args.cipherType );
62+ if (cipherName == " xsalsa20" ) {
63+ cipherInstance = std::make_shared<XSalsa20Cipher>();
64+ cipherInstance->setArgs (args);
65+ cipherInstance->init (args.cipherKey , args.iv );
66+ return cipherInstance;
67+ }
68+
69+ // Unsupported cipher type
70+ throw std::runtime_error (" Unsupported or unknown cipher type: " + args.cipherType );
71+ };
72+
5773};
5874
5975} // namespace margelo::nitro::crypto
0 commit comments