Implemented bit flipping fuzz test.
Moved random encryption to its own file. BUG= TEST= Review URL: https://webrtc-codereview.appspot.com/392017 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1771 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
b4556cd29a
commit
52b59d095e
@ -8,129 +8,141 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "gflags/gflags.h"
|
||||
#include "video_engine/include/vie_encryption.h"
|
||||
#include "video_engine/test/auto_test/automated/two_windows_fixture.h"
|
||||
#include "video_engine/test/auto_test/helpers/bit_flip_encryption.h"
|
||||
#include "video_engine/test/auto_test/helpers/random_encryption.h"
|
||||
#include "video_engine/test/auto_test/helpers/vie_window_creator.h"
|
||||
#include "video_engine/test/auto_test/interface/tb_capture_device.h"
|
||||
#include "video_engine/test/auto_test/interface/tb_interfaces.h"
|
||||
#include "video_engine/test/auto_test/interface/tb_video_channel.h"
|
||||
#include "video_engine/test/auto_test/interface/vie_autotest_window_manager_interface.h"
|
||||
#include "video_engine/test/auto_test/primitives/general_primitives.h"
|
||||
#include "video_engine/vie_defines.h"
|
||||
|
||||
namespace {
|
||||
|
||||
DEFINE_int32(rtp_fuzz_test_rand_seed, 0, "The rand seed to use for "
|
||||
"the RTP fuzz test. Defaults to time(). 0 cannot be specified.");
|
||||
"the RTP fuzz test. Defaults to time(). 0 cannot be specified.");
|
||||
|
||||
class ViERtpFuzzTest : public TwoWindowsFixture {
|
||||
protected:
|
||||
TbVideoChannel* video_channel_;
|
||||
TbInterfaces* video_engine_;
|
||||
TbCaptureDevice* capture_device_;
|
||||
|
||||
void SetUp() {
|
||||
video_engine_ = new TbInterfaces(
|
||||
"ViERtpTryInjectingRandomPacketsIntoRtpStream");
|
||||
video_channel_ = new TbVideoChannel(
|
||||
*video_engine_, webrtc::kVideoCodecVP8);
|
||||
capture_device_ = new TbCaptureDevice(*video_engine_);
|
||||
|
||||
capture_device_->ConnectTo(video_channel_->videoChannel);
|
||||
|
||||
// Enable PLI RTCP, which will allow the video engine to recover better.
|
||||
video_engine_->rtp_rtcp->SetKeyFrameRequestMethod(
|
||||
video_channel_->videoChannel, webrtc::kViEKeyFrameRequestPliRtcp);
|
||||
|
||||
video_channel_->StartReceive();
|
||||
video_channel_->StartSend();
|
||||
|
||||
RenderInWindow(
|
||||
video_engine_->render, capture_device_->captureId, window_1_, 0);
|
||||
RenderInWindow(
|
||||
video_engine_->render, video_channel_->videoChannel, window_2_, 1);
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
delete capture_device_;
|
||||
delete video_channel_;
|
||||
delete video_engine_;
|
||||
}
|
||||
|
||||
unsigned int FetchRandSeed() {
|
||||
if (FLAGS_rtp_fuzz_test_rand_seed != 0) {
|
||||
return FLAGS_rtp_fuzz_test_rand_seed;
|
||||
}
|
||||
return std::time(NULL);
|
||||
}
|
||||
|
||||
// Pass in a number [0, 1] which will be the bit flip probability per byte.
|
||||
void BitFlipFuzzTest(float flip_probability) {
|
||||
unsigned int rand_seed = FetchRandSeed();
|
||||
ViETest::Log("Running test with rand seed %d.", rand_seed);
|
||||
|
||||
ViETest::Log("Running as usual. You should see video output.");
|
||||
AutoTestSleep(2000);
|
||||
|
||||
ViETest::Log("Starting to flip bits in packets (%f%% chance per byte).",
|
||||
flip_probability * 100);
|
||||
BitFlipEncryption bit_flip_encryption(rand_seed, flip_probability);
|
||||
video_engine_->encryption->RegisterExternalEncryption(
|
||||
video_channel_->videoChannel, bit_flip_encryption);
|
||||
|
||||
AutoTestSleep(5000);
|
||||
|
||||
ViETest::Log("Back to normal. Flipped %d bits.",
|
||||
bit_flip_encryption.flip_count());
|
||||
video_engine_->encryption->DeregisterExternalEncryption(
|
||||
video_channel_->videoChannel);
|
||||
|
||||
AutoTestSleep(5000);
|
||||
}
|
||||
};
|
||||
|
||||
static int Saturate(int value, int min, int max) {
|
||||
return std::min(std::max(value, min), max);
|
||||
TEST_F(ViERtpFuzzTest, VideoEngineDealsWithASmallNumberOfTamperedPackets) {
|
||||
// Try 0.005% bit flip chance per byte.
|
||||
BitFlipFuzzTest(0.00005);
|
||||
}
|
||||
|
||||
// These algorithms attempt to create an uncrackable encryption
|
||||
// scheme by completely disregarding the input data.
|
||||
class RandomEncryption : public webrtc::Encryption {
|
||||
public:
|
||||
RandomEncryption(unsigned int rand_seed) {
|
||||
srand(rand_seed);
|
||||
}
|
||||
TEST_F(ViERtpFuzzTest, VideoEngineDealsWithAMediumNumberOfTamperedPackets) {
|
||||
// Try 0.05% bit flip chance per byte.
|
||||
BitFlipFuzzTest(0.0005);
|
||||
}
|
||||
|
||||
virtual void encrypt(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in, int* bytes_out) {
|
||||
GenerateRandomData(out_data, bytes_in, bytes_out);
|
||||
}
|
||||
TEST_F(ViERtpFuzzTest, VideoEngineDealsWithALargeNumberOfTamperedPackets) {
|
||||
// Try 0.5% bit flip chance per byte.
|
||||
BitFlipFuzzTest(0.005);
|
||||
}
|
||||
|
||||
virtual void decrypt(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in, int* bytes_out) {
|
||||
GenerateRandomData(out_data, bytes_in, bytes_out);
|
||||
}
|
||||
TEST_F(ViERtpFuzzTest, VideoEngineDealsWithAVeryLargeNumberOfTamperedPackets) {
|
||||
// Try 5% bit flip chance per byte.
|
||||
BitFlipFuzzTest(0.05);
|
||||
}
|
||||
|
||||
virtual void encrypt_rtcp(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in,
|
||||
int* bytes_out) {
|
||||
GenerateRandomData(out_data, bytes_in, bytes_out);
|
||||
}
|
||||
TEST_F(ViERtpFuzzTest,
|
||||
VideoEngineDealsWithAExtremelyLargeNumberOfTamperedPackets) {
|
||||
// Try 25% bit flip chance per byte (madness!)
|
||||
BitFlipFuzzTest(0.25);
|
||||
}
|
||||
|
||||
virtual void decrypt_rtcp(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in,
|
||||
int* bytes_out) {
|
||||
GenerateRandomData(out_data, bytes_in, bytes_out);
|
||||
}
|
||||
|
||||
private:
|
||||
// Generates some completely random data with roughly the right length.
|
||||
void GenerateRandomData(unsigned char* out_data, int bytes_in,
|
||||
int* bytes_out) {
|
||||
int out_length = MakeUpSimilarLength(bytes_in);
|
||||
for (int i = 0; i < out_length; i++) {
|
||||
// The modulo will skew the random distribution a bit, but I think it
|
||||
// will be random enough.
|
||||
out_data[i] = static_cast<unsigned char>(rand() % 256);
|
||||
}
|
||||
*bytes_out = out_length;
|
||||
}
|
||||
|
||||
// Makes up a length within +- 50 of the original length, without
|
||||
// overstepping the contract for encrypt / decrypt.
|
||||
int MakeUpSimilarLength(int original_length) {
|
||||
int sign = rand() - RAND_MAX / 2;
|
||||
int length = original_length + sign * rand() % 50;
|
||||
|
||||
return Saturate(length, 0, static_cast<int>(webrtc::kViEMaxMtu));
|
||||
}
|
||||
};
|
||||
TEST_F(ViERtpFuzzTest, VideoEngineDealsWithSeveralPeriodsOfTamperedPackets) {
|
||||
// Try 0.05% bit flip chance per byte.
|
||||
BitFlipFuzzTest(0.0005);
|
||||
BitFlipFuzzTest(0.0005);
|
||||
BitFlipFuzzTest(0.0005);
|
||||
}
|
||||
|
||||
TEST_F(ViERtpFuzzTest, VideoEngineRecoversAfterSomeCompletelyRandomPackets) {
|
||||
unsigned int rand_seed = FetchRandSeed();
|
||||
ViETest::Log("Running test with rand seed %d.", rand_seed);
|
||||
|
||||
TbInterfaces video_engine("ViERtpTryInjectingRandomPacketsIntoRtpStream");
|
||||
TbVideoChannel video_channel(video_engine, webrtc::kVideoCodecVP8);
|
||||
TbCaptureDevice capture_device(video_engine);
|
||||
|
||||
capture_device.ConnectTo(video_channel.videoChannel);
|
||||
|
||||
// Enable PLI RTCP, which will allow the video engine to recover better.
|
||||
video_engine.rtp_rtcp->SetKeyFrameRequestMethod(
|
||||
video_channel.videoChannel, webrtc::kViEKeyFrameRequestPliRtcp);
|
||||
|
||||
video_channel.StartReceive();
|
||||
video_channel.StartSend();
|
||||
|
||||
RenderInWindow(
|
||||
video_engine.render, capture_device.captureId, window_1_, 0);
|
||||
RenderInWindow(
|
||||
video_engine.render, video_channel.videoChannel, window_2_, 1);
|
||||
|
||||
ViETest::Log("Running as usual. You should see video output.");
|
||||
AutoTestSleep(2000);
|
||||
|
||||
ViETest::Log("Injecting completely random packets...");
|
||||
RandomEncryption random_encryption(rand_seed);
|
||||
video_engine.encryption->RegisterExternalEncryption(
|
||||
video_channel.videoChannel, random_encryption);
|
||||
video_engine_->encryption->RegisterExternalEncryption(
|
||||
video_channel_->videoChannel, random_encryption);
|
||||
|
||||
AutoTestSleep(5000);
|
||||
|
||||
ViETest::Log("Back to normal.");
|
||||
video_engine.encryption->DeregisterExternalEncryption(
|
||||
video_channel.videoChannel);
|
||||
video_engine_->encryption->DeregisterExternalEncryption(
|
||||
video_channel_->videoChannel);
|
||||
|
||||
AutoTestSleep(5000);
|
||||
}
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "video_engine/test/auto_test/helpers/bit_flip_encryption.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "video_engine/test/auto_test/interface/vie_autotest_defines.h"
|
||||
|
||||
float NormalizedRand() {
|
||||
return static_cast<float>(rand()) /
|
||||
static_cast<float>(RAND_MAX);
|
||||
}
|
||||
|
||||
BitFlipEncryption::BitFlipEncryption(unsigned int rand_seed,
|
||||
float flip_probability)
|
||||
: flip_probability_(flip_probability),
|
||||
flip_count_(0) {
|
||||
srand(rand_seed);
|
||||
}
|
||||
|
||||
void BitFlipEncryption::FlipSomeBitsInData(const unsigned char* in_data,
|
||||
unsigned char* out_data,
|
||||
int bytes_in, int* bytes_out) {
|
||||
for (int i = 0; i < bytes_in; i++) {
|
||||
out_data[i] = in_data[i];
|
||||
|
||||
if (NormalizedRand() < flip_probability_) {
|
||||
int bit_to_flip = rand() % 8;
|
||||
out_data[i] ^= 1 << bit_to_flip;
|
||||
flip_count_++;
|
||||
}
|
||||
}
|
||||
*bytes_out = bytes_in;
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef SRC_VIDEO_ENGINE_TEST_AUTO_TEST_HELPERS_BIT_FLIP_ENCRYPTION_H_
|
||||
#define SRC_VIDEO_ENGINE_TEST_AUTO_TEST_HELPERS_BIT_FLIP_ENCRYPTION_H_
|
||||
|
||||
#include "video_engine/include/vie_encryption.h"
|
||||
|
||||
// This encryption scheme will randomly flip bits every now and then in the
|
||||
// input data.
|
||||
class BitFlipEncryption : public webrtc::Encryption {
|
||||
public:
|
||||
// Args:
|
||||
// rand_seed: the seed to initialize the test's random generator with.
|
||||
// flip_probability: A number [0, 1] which is the percentage chance a bit
|
||||
// gets flipped in a particular byte.
|
||||
BitFlipEncryption(unsigned int rand_seed, float flip_probability);
|
||||
|
||||
virtual void encrypt(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in, int* bytes_out) {
|
||||
FlipSomeBitsInData(in_data, out_data, bytes_in, bytes_out);
|
||||
}
|
||||
|
||||
virtual void decrypt(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in, int* bytes_out) {
|
||||
FlipSomeBitsInData(in_data, out_data, bytes_in, bytes_out);
|
||||
}
|
||||
|
||||
virtual void encrypt_rtcp(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in,
|
||||
int* bytes_out) {
|
||||
FlipSomeBitsInData(in_data, out_data, bytes_in, bytes_out);
|
||||
}
|
||||
|
||||
virtual void decrypt_rtcp(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in,
|
||||
int* bytes_out) {
|
||||
FlipSomeBitsInData(in_data, out_data, bytes_in, bytes_out);
|
||||
}
|
||||
|
||||
int64_t flip_count() const { return flip_count_; }
|
||||
|
||||
private:
|
||||
// The flip probability ([0, 1]).
|
||||
float flip_probability_;
|
||||
// The number of bits we've flipped so far.
|
||||
int64_t flip_count_;
|
||||
|
||||
// Flips some bits in the data at random.
|
||||
void FlipSomeBitsInData(const unsigned char *in_data, unsigned char* out_data,
|
||||
int bytes_in, int* bytes_out);
|
||||
};
|
||||
|
||||
#endif // SRC_VIDEO_ENGINE_TEST_AUTO_TEST_HELPERS_BIT_FLIP_ENCRYPTION_H_
|
||||
46
src/video_engine/test/auto_test/helpers/random_encryption.cc
Normal file
46
src/video_engine/test/auto_test/helpers/random_encryption.cc
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "video_engine/test/auto_test/helpers/random_encryption.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
|
||||
#include "video_engine/vie_defines.h"
|
||||
|
||||
static int Saturate(int value, int min, int max) {
|
||||
return std::min(std::max(value, min), max);
|
||||
}
|
||||
|
||||
RandomEncryption::RandomEncryption(unsigned int rand_seed) {
|
||||
srand(rand_seed);
|
||||
}
|
||||
|
||||
// Generates some completely random data with roughly the right length.
|
||||
void RandomEncryption::GenerateRandomData(unsigned char* out_data, int bytes_in,
|
||||
int* bytes_out) {
|
||||
int out_length = MakeUpSimilarLength(bytes_in);
|
||||
for (int i = 0; i < out_length; i++) {
|
||||
// The modulo will skew the random distribution a bit, but I think it
|
||||
// will be random enough.
|
||||
out_data[i] = static_cast<unsigned char>(rand() % 256);
|
||||
}
|
||||
*bytes_out = out_length;
|
||||
}
|
||||
|
||||
// Makes up a length within +- 50 of the original length, without
|
||||
// overstepping the contract for encrypt / decrypt.
|
||||
int RandomEncryption::MakeUpSimilarLength(int original_length) {
|
||||
int sign = rand() - RAND_MAX / 2;
|
||||
int length = original_length + sign * rand() % 50;
|
||||
|
||||
return Saturate(length, 0, static_cast<int>(webrtc::kViEMaxMtu));
|
||||
}
|
||||
54
src/video_engine/test/auto_test/helpers/random_encryption.h
Normal file
54
src/video_engine/test/auto_test/helpers/random_encryption.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef SRC_VIDEO_ENGINE_TEST_AUTO_TEST_HELPERS_RANDOM_ENCRYPTION_H_
|
||||
#define SRC_VIDEO_ENGINE_TEST_AUTO_TEST_HELPERS_RANDOM_ENCRYPTION_H_
|
||||
|
||||
#include "video_engine/include/vie_encryption.h"
|
||||
|
||||
// These algorithms attempt to create an uncrackable encryption
|
||||
// scheme by completely disregarding the input data.
|
||||
class RandomEncryption : public webrtc::Encryption {
|
||||
public:
|
||||
explicit RandomEncryption(unsigned int rand_seed);
|
||||
|
||||
virtual void encrypt(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in, int* bytes_out) {
|
||||
GenerateRandomData(out_data, bytes_in, bytes_out);
|
||||
}
|
||||
|
||||
virtual void decrypt(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in, int* bytes_out) {
|
||||
GenerateRandomData(out_data, bytes_in, bytes_out);
|
||||
}
|
||||
|
||||
virtual void encrypt_rtcp(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in,
|
||||
int* bytes_out) {
|
||||
GenerateRandomData(out_data, bytes_in, bytes_out);
|
||||
}
|
||||
|
||||
virtual void decrypt_rtcp(int channel_no, unsigned char* in_data,
|
||||
unsigned char* out_data, int bytes_in,
|
||||
int* bytes_out) {
|
||||
GenerateRandomData(out_data, bytes_in, bytes_out);
|
||||
}
|
||||
|
||||
private:
|
||||
// Generates some completely random data with roughly the right length.
|
||||
void GenerateRandomData(unsigned char* out_data, int bytes_in,
|
||||
int* bytes_out);
|
||||
|
||||
// Makes up a length within +- 50 of the original length, without
|
||||
// overstepping the contract for encrypt / decrypt.
|
||||
int MakeUpSimilarLength(int original_length);
|
||||
};
|
||||
|
||||
#endif // SRC_VIDEO_ENGINE_TEST_AUTO_TEST_HELPERS_RANDOM_ENCRYPTION_H_
|
||||
@ -49,6 +49,10 @@
|
||||
'interface/vie_window_manager_factory.h',
|
||||
|
||||
# Helper classes
|
||||
'helpers/bit_flip_encryption.cc',
|
||||
'helpers/bit_flip_encryption.h',
|
||||
'helpers/random_encryption.cc',
|
||||
'helpers/random_encryption.h',
|
||||
'helpers/vie_fake_camera.cc',
|
||||
'helpers/vie_fake_camera.h',
|
||||
'helpers/vie_file_capture_device.cc',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user