Add AES-256-CTR-HMAC-SHA512 Sframe cipher suites

Expose the three AES-256-CTR-HMAC-SHA512 cipher suites from
draft-barnes-sframe-iana-256 (registry values 6, 7 and 8), already
implemented by third_party/sframe, through SframeCipherSuite and map
them in ToSframeCipherSuite. This brings the WebRTC enum in line with
the eight suites listed in the WebRTC Encoded Transform
SFrameCipherSuite IDL, which gained these suites in
https://github.com/w3c/webrtc-encoded-transform/pull/303.

Bug: webrtc:479862368
Change-Id: Ie5f0bbcccfeee9ea7dd69b253c75c8c47082fbc7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/507780
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Kacper Wasniowski <kwasniow@cisco.com>
Cr-Commit-Position: refs/heads/main@{#48822}
diff --git a/api/sframe/sframe_types.h b/api/sframe/sframe_types.h
index 2414bf3..f8e2d2b 100644
--- a/api/sframe/sframe_types.h
+++ b/api/sframe/sframe_types.h
@@ -24,6 +24,9 @@
   kAes128CtrHmacSha256_32,
   kAes128GcmSha256_128,
   kAes256GcmSha512_128,
+  kAes256CtrHmacSha512_80,
+  kAes256CtrHmacSha512_64,
+  kAes256CtrHmacSha512_32,
 };
 
 }  // namespace webrtc
diff --git a/modules/sframe/sframe_context_factory.cc b/modules/sframe/sframe_context_factory.cc
index 10c3079..9bd7ebc 100644
--- a/modules/sframe/sframe_context_factory.cc
+++ b/modules/sframe/sframe_context_factory.cc
@@ -30,6 +30,12 @@
       return sframe::CipherSuite::AES_GCM_128_SHA256;
     case SframeCipherSuite::kAes256GcmSha512_128:
       return sframe::CipherSuite::AES_GCM_256_SHA512;
+    case SframeCipherSuite::kAes256CtrHmacSha512_80:
+      return sframe::CipherSuite::AES_256_CTR_HMAC_SHA512_80;
+    case SframeCipherSuite::kAes256CtrHmacSha512_64:
+      return sframe::CipherSuite::AES_256_CTR_HMAC_SHA512_64;
+    case SframeCipherSuite::kAes256CtrHmacSha512_32:
+      return sframe::CipherSuite::AES_256_CTR_HMAC_SHA512_32;
   }
 }
 
diff --git a/modules/sframe/sframe_encryptor_decryptor_unittest.cc b/modules/sframe/sframe_encryptor_decryptor_unittest.cc
index 28b8048..7bf05cb 100644
--- a/modules/sframe/sframe_encryptor_decryptor_unittest.cc
+++ b/modules/sframe/sframe_encryptor_decryptor_unittest.cc
@@ -11,6 +11,7 @@
 #include <cstddef>
 #include <cstdint>
 #include <span>
+#include <string>
 #include <variant>
 #include <vector>
 
@@ -286,5 +287,70 @@
   EXPECT_EQ(failure->key_id, kKeyId);
 }
 
+class SframeCipherSuiteTest
+    : public ::testing::TestWithParam<SframeCipherSuite> {};
+
+TEST_P(SframeCipherSuiteTest, EncryptThenDecryptRoundTrip) {
+  scoped_refptr<SframeEncryptor> encryptor =
+      SframeEncryptor::Create(SframeMode::kPerFrame, GetParam());
+  scoped_refptr<SframeDecryptor> decryptor =
+      SframeDecryptor::Create(GetParam());
+  ASSERT_TRUE(encryptor->SetEncryptionKey(kKeyId, kKeyMaterial).ok());
+  ASSERT_TRUE(decryptor->AddDecryptionKey(kKeyId, kKeyMaterial).ok());
+
+  std::vector<uint8_t> ciphertext(
+      encryptor->GetMaxCiphertextByteSize(kPlaintext.size()));
+  RTCErrorOr<size_t> enc_result = encryptor->Encrypt(
+      kPlaintext, /*additional_data=*/{}, std::span<uint8_t>(ciphertext));
+  ASSERT_TRUE(enc_result.ok());
+  ciphertext.resize(enc_result.value());
+
+  std::vector<uint8_t> plaintext(
+      decryptor->GetMaxPlaintextByteSize(ciphertext.size()));
+  SframeDecryptResult dec_result = decryptor->Decrypt(
+      ciphertext, /*additional_data=*/{}, std::span<uint8_t>(plaintext));
+  const SframeDecryptSuccess* success =
+      std::get_if<SframeDecryptSuccess>(&dec_result);
+  ASSERT_NE(success, nullptr);
+  plaintext.resize(success->bytes_written);
+
+  EXPECT_EQ(plaintext, kPlaintext);
+}
+
+std::string CipherSuiteName(
+    const ::testing::TestParamInfo<SframeCipherSuite>& info) {
+  switch (info.param) {
+    case SframeCipherSuite::kAes128CtrHmacSha256_80:
+      return "Aes128CtrHmacSha256_80";
+    case SframeCipherSuite::kAes128CtrHmacSha256_64:
+      return "Aes128CtrHmacSha256_64";
+    case SframeCipherSuite::kAes128CtrHmacSha256_32:
+      return "Aes128CtrHmacSha256_32";
+    case SframeCipherSuite::kAes128GcmSha256_128:
+      return "Aes128GcmSha256_128";
+    case SframeCipherSuite::kAes256GcmSha512_128:
+      return "Aes256GcmSha512_128";
+    case SframeCipherSuite::kAes256CtrHmacSha512_80:
+      return "Aes256CtrHmacSha512_80";
+    case SframeCipherSuite::kAes256CtrHmacSha512_64:
+      return "Aes256CtrHmacSha512_64";
+    case SframeCipherSuite::kAes256CtrHmacSha512_32:
+      return "Aes256CtrHmacSha512_32";
+  }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    SframeCipherSuiteTest,
+    ::testing::Values(SframeCipherSuite::kAes128CtrHmacSha256_80,
+                      SframeCipherSuite::kAes128CtrHmacSha256_64,
+                      SframeCipherSuite::kAes128CtrHmacSha256_32,
+                      SframeCipherSuite::kAes128GcmSha256_128,
+                      SframeCipherSuite::kAes256GcmSha512_128,
+                      SframeCipherSuite::kAes256CtrHmacSha512_80,
+                      SframeCipherSuite::kAes256CtrHmacSha512_64,
+                      SframeCipherSuite::kAes256CtrHmacSha512_32),
+    CipherSuiteName);
+
 }  // namespace
 }  // namespace webrtc