Skip to content

Commit 33d81e7

Browse files
judyjosephyxieca
authored andcommitted
Support type7 encoded CAK key for macsec in config_db (#2892)
* Add decode type 7 alogorithm and use it to decode the encoded key from config_db * Remove the Error log added earlier for debugging * Add check for 66 bytes or 130 bytes encoded string based on cipher suite
1 parent d787d50 commit 33d81e7

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

cfgmgr/macsecmgr.cpp

+69-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ constexpr std::uint64_t RETRY_TIME = 30;
3434
/* retry interval, in millisecond */
3535
constexpr std::uint64_t RETRY_INTERVAL = 100;
3636

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+
3751
static void lexical_convert(const std::string &policy_str, MACsecMgr::MACsecProfile::Policy & policy)
3852
{
3953
SWSS_LOG_ENTER();
@@ -78,6 +92,60 @@ static void lexical_convert(const std::string &cipher_str, MACsecMgr::MACsecProf
7892
}
7993
}
8094

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+
81149
template<class T>
82150
static bool get_value(
83151
const MACsecMgr::TaskArgs & ta,
@@ -699,7 +767,7 @@ bool MACsecMgr::configureMACsec(
699767
port_name,
700768
network_id,
701769
"mka_cak",
702-
profile.primary_cak);
770+
decodeKey(profile.primary_cak, profile.cipher_suite));
703771

704772
wpa_cli_exec_and_check(
705773
session.sock,

0 commit comments

Comments
 (0)