@@ -1554,6 +1554,25 @@ static bool GetConfig(const Span<const uint8_t> args[],
15541554 "internal",
15551555 "external"
15561556 ]
1557+ },)"
1558+ R"( {
1559+ "algorithm": "KTS-IFC",
1560+ "revision": "Sp800-56Br2",
1561+ "iutId": "ABCD",
1562+ "function": ["keyPairGen", "partialVal"],
1563+ "keyGenerationMethods": ["rsakpg1-basic"],
1564+ "modulo": [2048, 3072, 4096],
1565+ "fixedPubExp": "010001",
1566+ "scheme": {
1567+ "KTS-OAEP-basic": {
1568+ "kasRole": ["initiator", "responder"],
1569+ "ktsMethod": {
1570+ "hashAlgs": ["SHA-1", "SHA2-224", "SHA2-256", "SHA2-384", "SHA2-512"],
1571+ "supportsNullAssociatedData": true
1572+ },
1573+ "l": 1024
1574+ }
1575+ }
15571576 }])" ;
15581577 return write_reply ({Span<const uint8_t >(
15591578 reinterpret_cast <const uint8_t *>(kConfig ), sizeof (kConfig ) - 1 )});
@@ -2849,6 +2868,106 @@ static bool RSASigVer(const Span<const uint8_t> args[],
28492868 return write_reply ({Span<const uint8_t >(&ok, 1 )});
28502869}
28512870
2871+ template <const EVP_MD *(MDFunc)()>
2872+ static bool RSAOAEPEncrypt (const Span<const uint8_t > args[],
2873+ ReplyCallback write_reply) {
2874+ const Span<const uint8_t > out_len_bytes = args[0 ];
2875+ const Span<const uint8_t > n_bytes = args[1 ];
2876+ const Span<const uint8_t > e_bytes = args[2 ];
2877+
2878+ uint32_t out_len = 0 ;
2879+ memcpy (&out_len, out_len_bytes.data (), sizeof (out_len));
2880+
2881+ BIGNUM *n = BN_new ();
2882+ BIGNUM *e = BN_new ();
2883+ bssl::UniquePtr<RSA> rsa (RSA_new ());
2884+
2885+ if (!BN_bin2bn (n_bytes.data (), n_bytes.size (), n) ||
2886+ !BN_bin2bn (e_bytes.data (), e_bytes.size (), e) ||
2887+ !RSA_set0_key (rsa.get (), n, e, nullptr )) {
2888+ return false ;
2889+ }
2890+
2891+ bssl::UniquePtr<EVP_PKEY> pkey (EVP_PKEY_new ());
2892+ if (!EVP_PKEY_set1_RSA (pkey.get (), rsa.get ())) {
2893+ return false ;
2894+ }
2895+
2896+ bssl::UniquePtr<EVP_PKEY_CTX> ctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
2897+ if (!ctx || !EVP_PKEY_encrypt_init (ctx.get ()) ||
2898+ !EVP_PKEY_CTX_set_rsa_padding (ctx.get (), RSA_PKCS1_OAEP_PADDING) ||
2899+ !EVP_PKEY_CTX_set_rsa_oaep_md (ctx.get (), MDFunc ())) {
2900+ return false ;
2901+ }
2902+
2903+ // Randomly generate the keying material to encrypt
2904+ std::vector<uint8_t > out (out_len);
2905+ RAND_bytes (out.data (), out.size ());
2906+
2907+ size_t ct_len = 0 ;
2908+ if (!EVP_PKEY_encrypt (ctx.get (), nullptr , &ct_len, out.data (), out.size ())) {
2909+ return false ;
2910+ }
2911+ std::vector<uint8_t > ct (ct_len);
2912+ if (!EVP_PKEY_encrypt (ctx.get (), ct.data (), &ct_len, out.data (),
2913+ out.size ())) {
2914+ return false ;
2915+ }
2916+ return write_reply ({Span<const uint8_t >(ct), Span<const uint8_t >(out)});
2917+ }
2918+
2919+ template <const EVP_MD *(MDFunc)()>
2920+ static bool RSAOAEPDecrypt (const Span<const uint8_t > args[],
2921+ ReplyCallback write_reply) {
2922+ const Span<const uint8_t > input = args[0 ];
2923+ const Span<const uint8_t > n_bytes = args[1 ];
2924+ const Span<const uint8_t > e_bytes = args[2 ];
2925+ const Span<const uint8_t > q_bytes = args[3 ];
2926+ const Span<const uint8_t > p_bytes = args[4 ];
2927+ const Span<const uint8_t > d_bytes = args[5 ];
2928+
2929+ BIGNUM *n = BN_new ();
2930+ BIGNUM *e = BN_new ();
2931+ BIGNUM *p = BN_new ();
2932+ BIGNUM *q = BN_new ();
2933+ BIGNUM *d = BN_new ();
2934+ bssl::UniquePtr<RSA> rsa (RSA_new ());
2935+
2936+ if (!BN_bin2bn (n_bytes.data (), n_bytes.size (), n) ||
2937+ !BN_bin2bn (e_bytes.data (), e_bytes.size (), e) ||
2938+ !BN_bin2bn (d_bytes.data (), d_bytes.size (), d) ||
2939+ !BN_bin2bn (p_bytes.data (), p_bytes.size (), p) ||
2940+ !BN_bin2bn (q_bytes.data (), q_bytes.size (), q) ||
2941+ !RSA_set0_key (rsa.get (), n, e, d) || !RSA_set0_factors (rsa.get (), p, q)) {
2942+ return false ;
2943+ }
2944+
2945+ bssl::UniquePtr<EVP_PKEY> pkey (EVP_PKEY_new ());
2946+ if (!EVP_PKEY_set1_RSA (pkey.get (), rsa.get ())) {
2947+ return false ;
2948+ }
2949+
2950+ bssl::UniquePtr<EVP_PKEY_CTX> ctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
2951+ if (!ctx || !EVP_PKEY_decrypt_init (ctx.get ()) ||
2952+ !EVP_PKEY_CTX_set_rsa_padding (ctx.get (), RSA_PKCS1_OAEP_PADDING) ||
2953+ !EVP_PKEY_CTX_set_rsa_oaep_md (ctx.get (), MDFunc ())) {
2954+ return false ;
2955+ }
2956+
2957+ size_t out_len = 0 ;
2958+ if (!EVP_PKEY_decrypt (ctx.get (), nullptr , &out_len, input.data (),
2959+ input.size ())) {
2960+ return false ;
2961+ }
2962+ std::vector<uint8_t > out (out_len);
2963+ if (!EVP_PKEY_decrypt (ctx.get (), out.data (), &out_len, input.data (),
2964+ input.size ())) {
2965+ return false ;
2966+ }
2967+ out.resize (out_len);
2968+ return write_reply ({Span<const uint8_t >(out)});
2969+ }
2970+
28522971template <const EVP_MD *(MDFunc)()>
28532972static bool TLSKDF (const Span<const uint8_t > args[],
28542973 ReplyCallback write_reply) {
@@ -3881,6 +4000,16 @@ static struct {
38814000 {" KDA/OneStep/HMAC-SHA2-512" , 4 , SSKDF_HMAC<EVP_sha512>},
38824001 {" KDA/OneStep/HMAC-SHA2-512/224" , 4 , SSKDF_HMAC<EVP_sha512_224>},
38834002 {" KDA/OneStep/HMAC-SHA2-512/256" , 4 , SSKDF_HMAC<EVP_sha512_256>},
4003+ {" KTS/OAEP/SHA-1/initiate" , 3 , RSAOAEPEncrypt<EVP_sha1>},
4004+ {" KTS/OAEP/SHA2-224/initiate" , 3 , RSAOAEPEncrypt<EVP_sha224>},
4005+ {" KTS/OAEP/SHA2-256/initiate" , 3 , RSAOAEPEncrypt<EVP_sha256>},
4006+ {" KTS/OAEP/SHA2-384/initiate" , 3 , RSAOAEPEncrypt<EVP_sha384>},
4007+ {" KTS/OAEP/SHA2-512/initiate" , 3 , RSAOAEPEncrypt<EVP_sha512>},
4008+ {" KTS/OAEP/SHA-1/respond" , 6 , RSAOAEPDecrypt<EVP_sha1>},
4009+ {" KTS/OAEP/SHA2-224/respond" , 6 , RSAOAEPDecrypt<EVP_sha224>},
4010+ {" KTS/OAEP/SHA2-256/respond" , 6 , RSAOAEPDecrypt<EVP_sha256>},
4011+ {" KTS/OAEP/SHA2-384/respond" , 6 , RSAOAEPDecrypt<EVP_sha384>},
4012+ {" KTS/OAEP/SHA2-512/respond" , 6 , RSAOAEPDecrypt<EVP_sha512>},
38844013 {" SSHKDF/SHA-1/ivCli" , 4 ,
38854014 SSHKDF<EVP_sha1, EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV>},
38864015 {" SSHKDF/SHA2-224/ivCli" , 4 ,
0 commit comments