@@ -34,6 +34,20 @@ constexpr std::uint64_t RETRY_TIME = 30;
34
34
/* retry interval, in millisecond */
35
35
constexpr std::uint64_t RETRY_INTERVAL = 100 ;
36
36
37
+ /*
38
+ * The input cipher_str is the encoded string which can be either of length 66 bytes or 130 bytes.
39
+ *
40
+ * 66 bytes of length, for 128-byte cipher suite
41
+ * - first 2 bytes of the string will be the index from the magic salt string.
42
+ * - remaining 64 bytes will be encoded string from the 32-byte plain text CAK input string.
43
+ *
44
+ * 130 bytes of length, for 256-byte cipher suite
45
+ * - first 2 bytes of the string will be the index from the magic salt string.
46
+ * - remaining 128 bytes will be encoded string from the 32 byte plain text CAK input string.
47
+ */
48
+ constexpr std::size_t AES_LEN_128_BYTE = 66 ;
49
+ constexpr std::size_t AES_LEN_256_BYTE = 130 ;
50
+
37
51
static void lexical_convert (const std::string &policy_str, MACsecMgr::MACsecProfile::Policy & policy)
38
52
{
39
53
SWSS_LOG_ENTER ();
@@ -78,6 +92,60 @@ static void lexical_convert(const std::string &cipher_str, MACsecMgr::MACsecProf
78
92
}
79
93
}
80
94
95
+
96
+
97
+ /* Decodes a Type 7 encoded input.
98
+ *
99
+ * The Type 7 encoding consists of two decimal digits(encoding the salt), followed a series of hexadecimal characters,
100
+ * two for every byte in the encoded password. An example encoding(of "password") is 044B0A151C36435C0D.
101
+ * This has a salt/offset of 4 (04 in the example), and encodes password via 4B0A151C36435C0D.
102
+ *
103
+ * The algorithm is a straightforward XOR Cipher that relies on the following ascii-encoded 53-byte constant:
104
+ * "dsfd;kfoA,.iyewrkldJKDHSUBsgvca69834ncxv9873254k;fg87"
105
+ *
106
+ * Decode()
107
+ * Get the salt index from the first 2 chars
108
+ * For each byte in the provided text after the encoded salt:
109
+ * j = (salt index + 1) % 53
110
+ * XOR the i'th byte of the password with the j'th byte of the magic constant.
111
+ * append to the decoded string.
112
+ */
113
+ static std::string decodeKey (const std::string &cipher_str, const MACsecMgr::MACsecProfile::CipherSuite & cipher_suite)
114
+ {
115
+ int salts[] = { 0x64 , 0x73 , 0x66 , 0x64 , 0x3B , 0x6B , 0x66 , 0x6F , 0x41 , 0x2C , 0x2E , 0x69 , 0x79 , 0x65 , 0x77 , 0x72 , 0x6B , 0x6C , 0x64 , 0x4A , 0x4B , 0x44 , 0x48 , 0x53 , 0x55 , 0x42 , 0x73 , 0x67 , 0x76 , 0x63 , 0x61 , 0x36 , 0x39 , 0x38 , 0x33 , 0x34 , 0x6E , 0x63 , 0x78 , 0x76 , 0x39 , 0x38 , 0x37 , 0x33 , 0x32 , 0x35 , 0x34 , 0x6B , 0x3B , 0x66 , 0x67 , 0x38 , 0x37 };
116
+
117
+ std::string decodedPassword = std::string (" " );
118
+ std::string cipher_hex_str = std::string (" " );
119
+ unsigned int hex_int, saltIdx;
120
+
121
+ if ((cipher_suite == MACsecMgr::MACsecProfile::CipherSuite::GCM_AES_128) ||
122
+ (cipher_suite == MACsecMgr::MACsecProfile::CipherSuite::GCM_AES_XPN_128))
123
+ {
124
+ if (cipher_str.length () != AES_LEN_128_BYTE)
125
+ throw std::invalid_argument (" Invalid length for cipher_string : " + cipher_str);
126
+ }
127
+ else if ((cipher_suite == MACsecMgr::MACsecProfile::CipherSuite::GCM_AES_256) ||
128
+ (cipher_suite == MACsecMgr::MACsecProfile::CipherSuite::GCM_AES_XPN_256))
129
+ {
130
+ if (cipher_str.length () != AES_LEN_256_BYTE)
131
+ throw std::invalid_argument (" Invalid length for cipher_string : " + cipher_str);
132
+ }
133
+
134
+ // Get the salt index from the cipher_str
135
+ saltIdx = (unsigned int ) stoi (cipher_str.substr (0 ,2 ));
136
+
137
+ // Convert the hex string (eg: "aabbcc") to hex integers (eg: 0xaa, 0xbb, 0xcc) taking a substring of 2 chars at a time
138
+ // and do xor with the magic salt string
139
+ for (size_t i = 2 ; i < cipher_str.length (); i += 2 ) {
140
+ std::stringstream ss;
141
+ ss << std::hex << cipher_str.substr (i,2 );
142
+ ss >> hex_int;
143
+ decodedPassword += (char )(hex_int ^ salts[saltIdx++ % (sizeof (salts)/sizeof (salts[0 ]))]);
144
+ }
145
+
146
+ return decodedPassword;
147
+ }
148
+
81
149
template <class T >
82
150
static bool get_value (
83
151
const MACsecMgr::TaskArgs & ta,
@@ -699,7 +767,7 @@ bool MACsecMgr::configureMACsec(
699
767
port_name,
700
768
network_id,
701
769
" mka_cak" ,
702
- profile.primary_cak );
770
+ decodeKey ( profile.primary_cak , profile. cipher_suite ) );
703
771
704
772
wpa_cli_exec_and_check (
705
773
session.sock ,
0 commit comments