Skip to content

Commit 4d868b9

Browse files
committed
Crypto: Simplify session key derivation code
1 parent defe785 commit 4d868b9

1 file changed

Lines changed: 29 additions & 26 deletions

File tree

xcloud/protocol/srtp_crypto.py

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -132,21 +132,39 @@ def from_bytes(cls, master_key: bytes, master_salt: bytes):
132132
)
133133

134134
@staticmethod
135-
def _derive_single_key(input_key: bytes, key_index: int = 0) -> bytes:
136-
keysize = len(input_key)
135+
def _crypt_ctr_oneshot(key: bytes, iv: bytes, plaintext: bytes, max_bytes: Optional[int] = None):
136+
"""
137+
Encrypt data with AES-CTR (one-shot)
138+
"""
139+
cipher = Cipher(algorithms.AES(key), modes.CTR(iv))
140+
encryptor = cipher.encryptor()
141+
cipher_out = encryptor.update(plaintext) + encryptor.finalize()
142+
if max_bytes:
143+
# Trim to desired output
144+
cipher_out = cipher_out[:max_bytes]
145+
return cipher_out
146+
147+
@staticmethod
148+
def _derive_single_key(
149+
master_key: bytes,
150+
master_salt: bytes,
151+
key_index: Optional[int] = 0,
152+
max_bytes: Optional[int] = 16
153+
) -> bytes:
154+
keysize = len(master_salt)
137155
keyout = bytearray(b'\x00' * 16)
138156

139157
if keysize >= 14:
140158
keysize = 14
141159

142160
if keysize:
143-
keyout[13] = input_key[keysize - 1]
161+
keyout[13] = master_salt[keysize - 1]
144162
if keysize != 1:
145-
keyout[12] = input_key[keysize - 2]
163+
keyout[12] = master_salt[keysize - 2]
146164
if keysize >= 3:
147165
pos = 0
148166
for _ in range(2, keysize):
149-
keyout[pos + 11] = input_key[pos + keysize - 3]
167+
keyout[pos + 11] = master_salt[pos + keysize - 3]
150168
pos -= 1
151169

152170
if keysize <= 13:
@@ -163,30 +181,16 @@ def _derive_single_key(input_key: bytes, key_index: int = 0) -> bytes:
163181
value_to_xor ^= (key_index * 0x1000000)
164182
keyout = keyout[:4] + struct.pack('<I', value_to_xor) + keyout[8:]
165183
assert len(keyout) == len_before_xor
166-
return keyout
167184

168-
@staticmethod
169-
def _crypt_ctr_oneshot(key: bytes, iv: bytes, plaintext: bytes, max_bytes: Optional[int] = None):
170-
"""
171-
Encrypt data with AES-CTR (one-shot)
172-
"""
173-
cipher = Cipher(algorithms.AES(key), modes.CTR(iv))
174-
encryptor = cipher.encryptor()
175-
cipher_out = encryptor.update(plaintext) + encryptor.finalize()
176-
if max_bytes:
177-
# Trim to desired output
178-
cipher_out = cipher_out[:max_bytes]
179-
return cipher_out
185+
# Encrypt the key
186+
keyout = SrtpContext._crypt_ctr_oneshot(master_key, keyout, b'\x00' * 16, max_bytes=max_bytes)
187+
return keyout
180188

181189
@staticmethod
182190
def _derive_session_keys(master_key: bytes, master_salt: bytes) -> SrtpSessionKeys:
183-
tmp1 = SrtpContext._derive_single_key(master_salt, SrtpSessionKeys.SRTP_CRYPT)
184-
tmp2 = SrtpContext._derive_single_key(master_salt, SrtpSessionKeys.SRTP_AUTH)
185-
tmp3 = SrtpContext._derive_single_key(master_salt, SrtpSessionKeys.SRTP_SALT)
186-
187-
crypt_key = SrtpContext._crypt_ctr_oneshot(master_key, tmp1, b'\x00' * 16)
188-
auth_key = SrtpContext._crypt_ctr_oneshot(master_key, tmp2, b'\x00' * 16)
189-
salt_key = SrtpContext._crypt_ctr_oneshot(master_key, tmp3, b'\x00' * 16, max_bytes=14)
191+
crypt_key = SrtpContext._derive_single_key(master_key, master_salt, SrtpSessionKeys.SRTP_CRYPT)
192+
auth_key = SrtpContext._derive_single_key(master_key, master_salt, SrtpSessionKeys.SRTP_AUTH)
193+
salt_key = SrtpContext._derive_single_key(master_key, master_salt, SrtpSessionKeys.SRTP_SALT, max_bytes=14)
190194

191195
return SrtpSessionKeys(crypt_key, auth_key, salt_key)
192196

@@ -209,7 +213,6 @@ def _get_transformed_nonce(self, transform_direction: TransformDirection) -> byt
209213
# FIXME: Just tranforming the Nonce to a known value for
210214
# our single test packet
211215
nonce[-1] += 1
212-
213216
return nonce
214217

215218
def decrypt(self, data: bytes, aad: bytes) -> bytes:

0 commit comments

Comments
 (0)