• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The Chromium Authors
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 "crypto/aes_cbc.h"
6 
7 #include <cstring>
8 
9 #include "base/strings/string_number_conversions.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 
12 namespace {
13 
TEST(AesCbcTests,KnownAnswers)14 TEST(AesCbcTests, KnownAnswers) {
15   struct TestCase {
16     const char* key;
17     const char* iv;
18     const char* plaintext;
19     const char* ciphertext;
20   };
21 
22   constexpr auto cases = std::to_array<TestCase>({
23       // SP800-38a F.2.1, with a PKCS#5 padding block appended to it.
24       {
25           .key = "2b7e151628aed2a6abf7158809cf4f3c",
26           .iv = "000102030405060708090a0b0c0d0e0f",
27           .plaintext = "6bc1bee22e409f96e93d7e117393172a"
28                        "ae2d8a571e03ac9c9eb76fac45af8e51"
29                        "30c81c46a35ce411e5fbc1191a0a52ef"
30                        "f69f2445df4f9b17ad2b417be66c3710",
31           .ciphertext = "7649abac8119b246cee98e9b12e9197d"
32                         "5086cb9b507219ee95db113a917678b2"
33                         "73bed6b8e3c1743b7116e69e22229516"
34                         "3ff1caa1681fac09120eca307586e1a7"
35                         "8cb82807230e1321d3fae00d18cc2012",
36       },
37 
38       // Modification of SP800-38a F.2.6: stripped off a bit of plaintext, added
39       // padding block.
40       {.key =
41            "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
42        .iv = "000102030405060708090a0b0c0d0e0f",
43        .plaintext = "6bc1bee22e409f96e93d7e117393172a"
44                     "ae2d8a571e03ac9c9eb76fac45af8e51"
45                     "30c81c46a35ce411e5fbc1191a0a52ef"
46                     "f69f2445df4f9b17ad2b417be6",
47        .ciphertext = "f58c4c04d6e5f1ba779eabfb5f7bfbd6"
48                      "9cfc4e967edb808d679f777bc6702c7d"
49                      "39f23369a9d9bacfa530e26304231461"
50                      "c9aaf02a6a54e9e242ccbf48c59daca6"},
51   });
52 
53   for (const auto& c : cases) {
54     std::vector<uint8_t> key;
55     CHECK(base::HexStringToBytes(c.key, &key));
56 
57     std::array<uint8_t, crypto::aes_cbc::kBlockSize> iv;
58     CHECK(base::HexStringToSpan(c.iv, iv));
59 
60     std::vector<uint8_t> plaintext;
61     CHECK(base::HexStringToBytes(c.plaintext, &plaintext));
62 
63     std::vector<uint8_t> ciphertext;
64     CHECK(base::HexStringToBytes(c.ciphertext, &ciphertext));
65 
66     std::vector<uint8_t> computed_ciphertext =
67         crypto::aes_cbc::Encrypt(key, iv, plaintext);
68     EXPECT_EQ(computed_ciphertext, ciphertext);
69     std::optional<std::vector<uint8_t>> computed_plaintext =
70         crypto::aes_cbc::Decrypt(key, iv, computed_ciphertext);
71     ASSERT_TRUE(computed_plaintext.has_value());
72     EXPECT_EQ(*computed_plaintext, plaintext);
73   }
74 }
75 
TEST(AesCbcTests,DecryptFailure)76 TEST(AesCbcTests, DecryptFailure) {
77   std::vector<uint8_t> key;
78   std::array<uint8_t, crypto::aes_cbc::kBlockSize> iv;
79   std::vector<uint8_t> plaintext;
80 
81   CHECK(base::HexStringToBytes("2b7e151628aed2a6abf7158809cf4f3c", &key));
82   CHECK(base::HexStringToSpan("000102030405060708090a0b0c0d0e0f", iv));
83   CHECK(
84       base::HexStringToBytes("6bc1bee22e409f96e93d7e117393172a"
85                              "ae2d8a571e03ac9c9eb76fac45af8e51"
86                              "30c81c46a35ce411e5fbc1191a0a52ef"
87                              "f69f2445df4f9b17ad2b417be66c3710",
88                              &plaintext));
89 
90   std::vector<uint8_t> ciphertext =
91       crypto::aes_cbc::Encrypt(key, iv, plaintext);
92   ciphertext[ciphertext.size() - 1] ^= 0x01;
93   std::optional<std::vector<uint8_t>> result =
94       crypto::aes_cbc::Decrypt(key, iv, ciphertext);
95   ASSERT_FALSE(result.has_value());
96 }
97 
98 }  // namespace
99