Skip to content

Commit 87977ca

Browse files
committed
add failure tolerance for framecryptor. (#91)
* add failure tolerance for framecryptor. * add failureTolerance for android/objc. * fix: make H264's unencrypted_bytes consistent with js-sdk. * add SetSifTrailer.
1 parent 98fe34e commit 87977ca

File tree

8 files changed

+84
-16
lines changed

8 files changed

+84
-16
lines changed

api/crypto/frame_crypto_transformer.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ uint8_t get_unencrypted_bytes(webrtc::TransformableFrameInterface* frame,
136136
<< "NonParameterSetNalu::payload_size: " << index.payload_size
137137
<< ", nalu_type " << nalu_type << ", NaluIndex [" << idx++
138138
<< "] offset: " << index.payload_start_offset;
139-
break;
139+
return unencrypted_bytes;
140140
default:
141141
break;
142142
}
@@ -219,7 +219,7 @@ int AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
219219
}
220220

221221
if (!ok) {
222-
RTC_LOG(LS_ERROR) << "Failed to perform AES-GCM operation.";
222+
RTC_LOG(LS_WARNING) << "Failed to perform AES-GCM operation.";
223223
return OperationError;
224224
}
225225

@@ -510,7 +510,7 @@ void FrameCryptorTransformer::decryptFrame(
510510
uint8_t key_index = frame_trailer[1];
511511

512512
if (ivLength != getIvSize()) {
513-
RTC_LOG(LS_ERROR) << "FrameCryptorTransformer::decryptFrame() ivLength["
513+
RTC_LOG(LS_WARNING) << "FrameCryptorTransformer::decryptFrame() ivLength["
514514
<< static_cast<int>(ivLength) << "] != getIvSize()["
515515
<< static_cast<int>(getIvSize()) << "]";
516516
if (last_dec_error_ != FrameCryptionState::kDecryptionFailed) {
@@ -569,7 +569,7 @@ void FrameCryptorTransformer::decryptFrame(
569569
encrypted_payload, &buffer) == Success) {
570570
decryption_success = true;
571571
} else {
572-
RTC_LOG(LS_ERROR) << "FrameCryptorTransformer::decryptFrame() failed";
572+
RTC_LOG(LS_WARNING) << "FrameCryptorTransformer::decryptFrame() failed";
573573
std::shared_ptr<ParticipantKeyHandler::KeySet> ratcheted_key_set;
574574
auto currentKeyMaterial = key_set->material;
575575
if (key_provider_->options().ratchet_window_size > 0) {
@@ -593,7 +593,7 @@ void FrameCryptorTransformer::decryptFrame(
593593
decryption_success = true;
594594
// success, so we set the new key
595595
key_handler->SetKeyFromMaterial(new_material, key_index);
596-
key_handler->SetHasValidKey(true);
596+
key_handler->SetHasValidKey();
597597
if (last_dec_error_ != FrameCryptionState::kKeyRatcheted) {
598598
last_dec_error_ = FrameCryptionState::kKeyRatcheted;
599599
if (observer_)
@@ -622,7 +622,7 @@ void FrameCryptorTransformer::decryptFrame(
622622
if (!decryption_success) {
623623
if (last_dec_error_ != FrameCryptionState::kDecryptionFailed) {
624624
last_dec_error_ = FrameCryptionState::kDecryptionFailed;
625-
key_handler->SetHasValidKey(false);
625+
key_handler->DecryptionFailure();
626626
if (observer_)
627627
observer_->OnFrameCryptionStateChanged(participant_id_,
628628
last_dec_error_);

api/crypto/frame_crypto_transformer.h

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,14 @@ struct KeyProviderOptions {
4141
std::vector<uint8_t> ratchet_salt;
4242
std::vector<uint8_t> uncrypted_magic_bytes;
4343
int ratchet_window_size;
44-
KeyProviderOptions() : shared_key(false), ratchet_window_size(0) {}
44+
int failure_tolerance;
45+
KeyProviderOptions() : shared_key(false), ratchet_window_size(0), failure_tolerance(-1) {}
4546
KeyProviderOptions(KeyProviderOptions& copy)
4647
: shared_key(copy.shared_key),
4748
ratchet_salt(copy.ratchet_salt),
4849
uncrypted_magic_bytes(copy.uncrypted_magic_bytes),
49-
ratchet_window_size(copy.ratchet_window_size) {}
50+
ratchet_window_size(copy.ratchet_window_size),
51+
failure_tolerance(copy.failure_tolerance) {}
5052
};
5153

5254
class KeyProvider : public rtc::RefCountInterface {
@@ -74,6 +76,8 @@ class KeyProvider : public rtc::RefCountInterface {
7476
virtual const std::vector<uint8_t> ExportKey(const std::string participant_id,
7577
int key_index) const = 0;
7678

79+
virtual void SetSifTrailer(const std::vector<uint8_t> trailer) = 0;
80+
7781
virtual KeyProviderOptions& options() = 0;
7882

7983
protected:
@@ -116,7 +120,7 @@ class ParticipantKeyHandler {
116120
}
117121
SetKeyFromMaterial(new_material,
118122
key_index != -1 ? key_index : current_key_index_);
119-
SetHasValidKey(true);
123+
SetHasValidKey();
120124
return new_material;
121125
}
122126

@@ -127,7 +131,7 @@ class ParticipantKeyHandler {
127131

128132
virtual void SetKey(std::vector<uint8_t> password, int key_index) {
129133
SetKeyFromMaterial(password, key_index);
130-
SetHasValidKey(true);
134+
SetHasValidKey();
131135
}
132136

133137
std::vector<uint8_t> RatchetKeyMaterial(
@@ -156,9 +160,10 @@ class ParticipantKeyHandler {
156160
return has_valid_key_;
157161
}
158162

159-
void SetHasValidKey(bool has_valid_key) {
163+
void SetHasValidKey() {
160164
webrtc::MutexLock lock(&mutex_);
161-
has_valid_key_ = has_valid_key;
165+
decryption_failure_count_ = 0;
166+
has_valid_key_ = true;
162167
}
163168

164169
void SetKeyFromMaterial(std::vector<uint8_t> password, int key_index) {
@@ -170,8 +175,21 @@ class ParticipantKeyHandler {
170175
DeriveKeys(password, key_provider_->options().ratchet_salt, 128);
171176
}
172177

178+
void DecryptionFailure() {
179+
webrtc::MutexLock lock(&mutex_);
180+
if (key_provider_->options().failure_tolerance < 0) {
181+
return;
182+
}
183+
decryption_failure_count_ += 1;
184+
185+
if (decryption_failure_count_ > key_provider_->options().failure_tolerance) {
186+
has_valid_key_ = false;
187+
}
188+
}
189+
173190
private:
174191
bool has_valid_key_ = false;
192+
int decryption_failure_count_ = 0;
175193
mutable webrtc::Mutex mutex_;
176194
int current_key_index_ = 0;
177195
KeyProvider* key_provider_;
@@ -296,6 +314,11 @@ class DefaultKeyProviderImpl : public KeyProvider {
296314
return std::vector<uint8_t>();
297315
}
298316

317+
void SetSifTrailer(const std::vector<uint8_t> trailer) override {
318+
webrtc::MutexLock lock(&mutex_);
319+
options_.uncrypted_magic_bytes = trailer;
320+
}
321+
299322
KeyProviderOptions& options() override { return options_; }
300323

301324
private:

sdk/android/api/org/webrtc/FrameCryptorFactory.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
public class FrameCryptorFactory {
2020
public static FrameCryptorKeyProvider createFrameCryptorKeyProvider(
21-
boolean sharedKey, byte[] ratchetSalt, int ratchetWindowSize, byte[] uncryptedMagicBytes) {
22-
return nativeCreateFrameCryptorKeyProvider(sharedKey, ratchetSalt, ratchetWindowSize, uncryptedMagicBytes);
21+
boolean sharedKey, byte[] ratchetSalt, int ratchetWindowSize, byte[] uncryptedMagicBytes, int failureTolerance) {
22+
return nativeCreateFrameCryptorKeyProvider(sharedKey, ratchetSalt, ratchetWindowSize, uncryptedMagicBytes, failureTolerance);
2323
}
2424

2525
public static FrameCryptor createFrameCryptorForRtpSender(RtpSender rtpSender,
@@ -40,5 +40,5 @@ private static native FrameCryptor nativeCreateFrameCryptorForRtpReceiver(
4040
long rtpReceiver, String participantId, int algorithm, long nativeFrameCryptorKeyProvider);
4141

4242
private static native FrameCryptorKeyProvider nativeCreateFrameCryptorKeyProvider(
43-
boolean sharedKey, byte[] ratchetSalt, int ratchetWindowSize, byte[] uncryptedMagicBytes);
43+
boolean sharedKey, byte[] ratchetSalt, int ratchetWindowSize, byte[] uncryptedMagicBytes, int failureTolerance);
4444
}

sdk/android/api/org/webrtc/FrameCryptorKeyProvider.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ public byte[] exportKey(String participantId, int index) {
6060
return nativeExportKey(nativeKeyProvider, participantId, index);
6161
}
6262

63+
public void setSifTrailer(byte[] sifTrailer) {
64+
checkKeyProviderExists();
65+
nativeSetSifTrailer(nativeKeyProvider, sifTrailer);
66+
}
67+
6368
public void dispose() {
6469
checkKeyProviderExists();
6570
JniCommon.nativeReleaseRef(nativeKeyProvider);
@@ -83,4 +88,6 @@ private static native byte[] nativeRatchetKey(
8388
long keyProviderPointer, String participantId, int index);
8489
private static native byte[] nativeExportKey(
8590
long keyProviderPointer, String participantId, int index);
91+
private static native void nativeSetSifTrailer(
92+
long keyProviderPointer, byte[] sifTrailer);
8693
}

sdk/android/src/jni/pc/frame_cryptor.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ JNI_FrameCryptorFactory_CreateFrameCryptorKeyProvider(
171171
jboolean j_shared,
172172
const base::android::JavaParamRef<jbyteArray>& j_ratchetSalt,
173173
jint j_ratchetWindowSize,
174-
const base::android::JavaParamRef<jbyteArray>& j_uncryptedMagicBytes) {
174+
const base::android::JavaParamRef<jbyteArray>& j_uncryptedMagicBytes,
175+
jint j_failureTolerance) {
175176
auto ratchetSalt = JavaToNativeByteArray(env, j_ratchetSalt);
176177
KeyProviderOptions options;
177178
options.ratchet_salt =
@@ -182,6 +183,7 @@ JNI_FrameCryptorFactory_CreateFrameCryptorKeyProvider(
182183
options.uncrypted_magic_bytes =
183184
std::vector<uint8_t>(uncryptedMagicBytes.begin(), uncryptedMagicBytes.end());
184185
options.shared_key = j_shared;
186+
options.failure_tolerance = j_failureTolerance;
185187
return NativeToJavaFrameCryptorKeyProvider(
186188
env, rtc::make_ref_counted<webrtc::DefaultKeyProviderImpl>(options));
187189
}

sdk/android/src/jni/pc/frame_cryptor_key_provider.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,14 @@ JNI_FrameCryptorKeyProvider_ExportKey(
110110
return NativeToJavaByteArray(env, rtc::ArrayView<int8_t>(int8tKey));
111111
}
112112

113+
static void JNI_FrameCryptorKeyProvider_SetSifTrailer(
114+
JNIEnv* jni,
115+
jlong j_key_provider,
116+
const base::android::JavaParamRef<jbyteArray>& j_trailer) {
117+
auto trailer = JavaToNativeByteArray(jni, j_trailer);
118+
reinterpret_cast<webrtc::DefaultKeyProviderImpl*>(j_key_provider)
119+
->SetSifTrailer(std::vector<uint8_t>(trailer.begin(), trailer.end()));
120+
}
121+
113122
} // namespace jni
114123
} // namespace webrtc

sdk/objc/api/peerconnection/RTCFrameCryptorKeyProvider.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,19 @@ RTC_OBJC_EXPORT
3535

3636
- (NSData *)exportKey:(NSString *)participantId withIndex:(int)index;
3737

38+
- (void)setSifTrailer:(NSData *)trailer;
39+
3840
- (instancetype)initWithRatchetSalt:(NSData *)salt
3941
ratchetWindowSize:(int)windowSize
4042
sharedKeyMode:(BOOL)sharedKey
4143
uncryptedMagicBytes:(nullable NSData *)uncryptedMagicBytes;
4244

45+
- (instancetype)initWithRatchetSalt:(NSData *)salt
46+
ratchetWindowSize:(int)windowSize
47+
sharedKeyMode:(BOOL)sharedKey
48+
uncryptedMagicBytes:(nullable NSData *)uncryptedMagicBytes
49+
failureTolerance:(int)failureTolerance;
50+
4351
@end
4452

4553
NS_ASSUME_NONNULL_END

sdk/objc/api/peerconnection/RTCFrameCryptorKeyProvider.mm

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,25 @@ - (instancetype)initWithRatchetSalt:(NSData *)salt
3434
ratchetWindowSize:(int)windowSize
3535
sharedKeyMode:(BOOL)sharedKey
3636
uncryptedMagicBytes:(NSData *)uncryptedMagicBytes {
37+
return [self initWithRatchetSalt:salt
38+
ratchetWindowSize:windowSize
39+
sharedKeyMode:sharedKey
40+
uncryptedMagicBytes:uncryptedMagicBytes
41+
failureTolerance:-1];
42+
}
43+
44+
- (instancetype)initWithRatchetSalt:(NSData *)salt
45+
ratchetWindowSize:(int)windowSize
46+
sharedKeyMode:(BOOL)sharedKey
47+
uncryptedMagicBytes:(nullable NSData *)uncryptedMagicBytes
48+
failureTolerance:(int)failureTolerance {
3749
if (self = [super init]) {
3850
webrtc::KeyProviderOptions options;
3951
options.ratchet_salt = std::vector<uint8_t>((const uint8_t *)salt.bytes,
4052
((const uint8_t *)salt.bytes) + salt.length);
4153
options.ratchet_window_size = windowSize;
4254
options.shared_key = sharedKey;
55+
options.failure_tolerance = failureTolerance;
4356
if(uncryptedMagicBytes != nil) {
4457
options.uncrypted_magic_bytes = std::vector<uint8_t>((const uint8_t *)uncryptedMagicBytes.bytes,
4558
((const uint8_t *)uncryptedMagicBytes.bytes) + uncryptedMagicBytes.length);
@@ -82,4 +95,10 @@ - (NSData *)exportKey:(NSString *)participantId withIndex:(int)index {
8295
return [NSData dataWithBytes:nativeKey.data() length:nativeKey.size()];
8396
}
8497

98+
- (void)setSifTrailer:(NSData *)trailer {
99+
_nativeKeyProvider->SetSifTrailer(
100+
std::vector<uint8_t>((const uint8_t *)trailer.bytes,
101+
((const uint8_t *)trailer.bytes) + trailer.length));
102+
}
103+
85104
@end

0 commit comments

Comments
 (0)