@@ -340,6 +340,12 @@ static bool GetConfig(const Span<const uint8_t> args[],
340340 "direction": ["encrypt", "decrypt"],
341341 "keyLen": [128, 192, 256]
342342 },
343+ {
344+ "algorithm": "ACVP-AES-CFB128",
345+ "revision": "1.0",
346+ "direction": ["encrypt", "decrypt"],
347+ "keyLen": [128, 192, 256]
348+ },
343349 {
344350 "algorithm": "ACVP-AES-GCM",
345351 "revision": "1.0",
@@ -1760,6 +1766,58 @@ static bool AES_CBC(const Span<const uint8_t> args[],
17601766 {Span<const uint8_t >(result), Span<const uint8_t >(prev_result)});
17611767}
17621768
1769+ template <void (*CipherOp)(const uint8_t *in, uint8_t *out,
1770+ size_t bits, const AES_KEY *key,
1771+ uint8_t *ivec, int *num, int enc),
1772+ int Direction>
1773+ static bool AES_CFB (const Span<const uint8_t > args[],
1774+ ReplyCallback write_reply) {
1775+ AES_KEY key;
1776+ if (AES_set_encrypt_key (args[0 ].data (), args[0 ].size () * 8 , &key) != 0 ) {
1777+ return false ;
1778+ }
1779+ if (args[1 ].empty () || args[2 ].size () != AES_BLOCK_SIZE) {
1780+ return false ;
1781+ }
1782+ std::vector<uint8_t > input (args[1 ].begin (), args[1 ].end ());
1783+ std::vector<uint8_t > iv (args[2 ].begin (), args[2 ].end ());
1784+ const uint32_t iterations = GetIterations (args[3 ]);
1785+
1786+ std::vector<uint8_t > result (input.size ());
1787+ std::vector<uint8_t > prev_result, prev_input;
1788+
1789+ for (uint32_t j = 0 ; j < iterations; j++) {
1790+ prev_result = result;
1791+ if (j > 0 ) {
1792+ if (Direction == AES_ENCRYPT) {
1793+ iv = result;
1794+ } else {
1795+ iv = prev_input;
1796+ }
1797+ }
1798+
1799+ // CipherOp will mutate the given IV, but we need it later.
1800+ uint8_t iv_copy[AES_BLOCK_SIZE];
1801+ memcpy (iv_copy, iv.data (), sizeof (iv_copy));
1802+ int num = 0 ;
1803+ CipherOp (input.data (), result.data (), input.size (), &key, iv_copy,
1804+ &num, Direction);
1805+
1806+ if (Direction == AES_DECRYPT) {
1807+ prev_input = input;
1808+ }
1809+
1810+ if (j == 0 ) {
1811+ input = iv;
1812+ } else {
1813+ input = prev_result;
1814+ }
1815+ }
1816+
1817+ return write_reply (
1818+ {Span<const uint8_t >(result), Span<const uint8_t >(prev_result)});
1819+ }
1820+
17631821static bool AES_CTR (const Span<const uint8_t > args[],
17641822 ReplyCallback write_reply) {
17651823 static const uint32_t kOneIteration = 1 ;
@@ -3381,6 +3439,8 @@ static struct {
33813439 {" AES-XTS/decrypt" , 3 , AES_XTS<false >},
33823440 {" AES-CBC/encrypt" , 4 , AES_CBC<AES_set_encrypt_key, AES_ENCRYPT>},
33833441 {" AES-CBC/decrypt" , 4 , AES_CBC<AES_set_decrypt_key, AES_DECRYPT>},
3442+ {" AES-CFB128/encrypt" , 4 , AES_CFB<AES_cfb128_encrypt, AES_ENCRYPT>},
3443+ {" AES-CFB128/decrypt" , 4 , AES_CFB<AES_cfb128_encrypt, AES_DECRYPT>},
33843444 {" AES-CTR/encrypt" , 4 , AES_CTR},
33853445 {" AES-CTR/decrypt" , 4 , AES_CTR},
33863446 {" AES-GCM/seal" , 5 , AEADSeal<AESGCMSetup>},
0 commit comments