• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "cast/streaming/frame_crypto.h"
6 
7 #include <array>
8 #include <cstring>
9 #include <vector>
10 
11 #include "gtest/gtest.h"
12 #include "util/crypto/random_bytes.h"
13 
14 namespace openscreen {
15 namespace cast {
16 namespace {
17 
TEST(FrameCryptoTest,EncryptsAndDecryptsFrames)18 TEST(FrameCryptoTest, EncryptsAndDecryptsFrames) {
19   // Prepare two frames with different FrameIds, but having the same payload
20   // bytes.
21   EncodedFrame frame0;
22   frame0.frame_id = FrameId::first();
23   const char kPayload[] = "The quick brown fox jumps over the lazy dog.";
24   std::vector<uint8_t> buffer(
25       reinterpret_cast<const uint8_t*>(kPayload),
26       reinterpret_cast<const uint8_t*>(kPayload) + sizeof(kPayload));
27   frame0.data = absl::Span<uint8_t>(buffer);
28   EncodedFrame frame1;
29   frame1.frame_id = frame0.frame_id + 1;
30   frame1.data = frame0.data;
31 
32   const std::array<uint8_t, 16> key = GenerateRandomBytes16();
33   const std::array<uint8_t, 16> iv = GenerateRandomBytes16();
34   EXPECT_NE(0, memcmp(key.data(), iv.data(), sizeof(key)));
35   const FrameCrypto crypto(key, iv);
36 
37   // Encrypt both frames, and confirm the encrypted data is something other than
38   // the plaintext, and that both frames have different encrypted data.
39   const EncryptedFrame encrypted_frame0 = crypto.Encrypt(frame0);
40   EXPECT_EQ(frame0.frame_id, encrypted_frame0.frame_id);
41   ASSERT_EQ(static_cast<int>(frame0.data.size()),
42             FrameCrypto::GetPlaintextSize(encrypted_frame0));
43   EXPECT_NE(0, memcmp(frame0.data.data(), encrypted_frame0.data.data(),
44                       frame0.data.size()));
45   const EncryptedFrame encrypted_frame1 = crypto.Encrypt(frame1);
46   EXPECT_EQ(frame1.frame_id, encrypted_frame1.frame_id);
47   ASSERT_EQ(static_cast<int>(frame1.data.size()),
48             FrameCrypto::GetPlaintextSize(encrypted_frame1));
49   EXPECT_NE(0, memcmp(frame1.data.data(), encrypted_frame1.data.data(),
50                       frame1.data.size()));
51   ASSERT_EQ(encrypted_frame0.data.size(), encrypted_frame1.data.size());
52   EXPECT_NE(0,
53             memcmp(encrypted_frame0.data.data(), encrypted_frame1.data.data(),
54                    encrypted_frame0.data.size()));
55 
56   // Now, decrypt the encrypted frames, and confirm the original payload
57   // plaintext is retrieved.
58   EncodedFrame decrypted_frame0;
59   std::vector<uint8_t> decrypted_frame0_buffer(
60       FrameCrypto::GetPlaintextSize(encrypted_frame0));
61   decrypted_frame0.data = absl::Span<uint8_t>(decrypted_frame0_buffer);
62   crypto.Decrypt(encrypted_frame0, &decrypted_frame0);
63   EXPECT_EQ(frame0.frame_id, decrypted_frame0.frame_id);
64   ASSERT_EQ(frame0.data.size(), decrypted_frame0.data.size());
65   EXPECT_EQ(0, memcmp(frame0.data.data(), decrypted_frame0.data.data(),
66                       frame0.data.size()));
67 
68   EncodedFrame decrypted_frame1;
69   std::vector<uint8_t> decrypted_frame1_buffer(
70       FrameCrypto::GetPlaintextSize(encrypted_frame1));
71   decrypted_frame1.data = absl::Span<uint8_t>(decrypted_frame1_buffer);
72   crypto.Decrypt(encrypted_frame1, &decrypted_frame1);
73   EXPECT_EQ(frame1.frame_id, decrypted_frame1.frame_id);
74   ASSERT_EQ(frame1.data.size(), decrypted_frame1.data.size());
75   EXPECT_EQ(0, memcmp(frame1.data.data(), decrypted_frame1.data.data(),
76                       frame1.data.size()));
77 }
78 
79 }  // namespace
80 }  // namespace cast
81 }  // namespace openscreen
82