Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Unified Diff: third_party/tlslite/tlslite/tlsrecordlayer.py

Issue 875683002: Implement AES-GCM in tlslite. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/tlslite/tlslite/tlsrecordlayer.py
diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py
index a09499d26c50c9b696b2c34be391db4dae46a146..545ff6347407e3af3c2d7d49d88c5ca0f2366f3e 100644
--- a/third_party/tlslite/tlslite/tlsrecordlayer.py
+++ b/third_party/tlslite/tlslite/tlsrecordlayer.py
@@ -11,7 +11,8 @@ from __future__ import generators
from .utils.compat import *
from .utils.cryptomath import *
-from .utils.cipherfactory import createAES, createRC4, createTripleDES
+from .utils.cipherfactory import createAESGCM, createAES, createRC4, \
+ createTripleDES
from .utils.codec import *
from .errors import *
from .messages import *
@@ -594,8 +595,26 @@ class TLSRecordLayer(object):
#Encrypt for Block or Stream Cipher
Ryan Sleevi 2015/01/29 20:50:48 comment update?
davidben 2015/01/29 21:40:59 Done.
if self._writeState.encContext:
+ #Seal (for AEAD)
+ if self._writeState.encContext.isAEAD:
+ #Assemble the AD.
Ryan Sleevi 2015/01/29 20:50:49 expand this acronym? #Assemble the authenticated
davidben 2015/01/29 21:40:59 Done.
+ seqnumBytes = self._writeState.getSeqNumBytes()
Ryan Sleevi 2015/01/29 20:50:48 nit: naming wise, should this be seqNumBytes?
davidben 2015/01/29 21:40:59 Copy-and-paste from MAC block above, but I agree.
+ ad = seqnumBytes + bytearray([contentType, self.version[0],
+ self.version[1], len(b)//256,
+ len(b)%256])
+
+ #The nonce is always the fixed nonce and the sequence number.
+ nonce = self._writeState.fixedNonce + seqnumBytes
+ assert len(nonce) == self._writeState.encContext.nonceLength
+
+ b = self._writeState.encContext.seal(nonce, b, ad)
+
+ #The only AEAD supported, AES-GCM, has an explicit variable
+ #nonce.
Ryan Sleevi 2015/01/29 20:50:49 "explicit variable nonce" - this is just explicit
davidben 2015/01/29 21:40:59 As opposed to the fixed half of the nonce. (GCM no
+ b = seqnumBytes + b
+
#Add padding and encrypt (for Block Cipher):
- if self._writeState.encContext.isBlockCipher:
+ elif self._writeState.encContext.isBlockCipher:
#Add TLS 1.1 fixed block
if self.version >= (3,2):
@@ -967,6 +986,36 @@ class TLSRecordLayer(object):
def _decryptRecord(self, recordType, b):
if self._readState.encContext:
+ #Open if it's an AEAD.
+ if self._readState.encContext.isAEAD:
+ #The only AEAD supported, AES-GCM, has an explicit variable
+ #nonce.
+ explicitNonceLength = 8
+ if explicitNonceLength > len(b):
+ #Publicly invalid.
+ for result in self._sendError(
+ AlertDescription.bad_record_mac,
+ "MAC failure (or padding failure)"):
+ yield result
+ nonce = self._readState.fixedNonce + b[:explicitNonceLength]
+ b = b[8:]
+
+ #Assemble the AD.
+ seqnumBytes = self._readState.getSeqNumBytes()
+ plaintextLen = len(b) - self._readState.encContext.tagLength
agl 2015/01/29 19:38:17 This can end up negative, but that doesn't appear
davidben 2015/01/29 21:40:59 Added a check anyway for good measure. I think a n
+ ad = seqnumBytes + bytearray([recordType, self.version[0],
+ self.version[1],
+ plaintextLen//256,
+ plaintextLen%256])
+
+ b = self._readState.encContext.open(nonce, b, ad)
+ if b is None:
+ for result in self._sendError(
+ AlertDescription.bad_record_mac,
+ "MAC failure (or padding failure)"):
+ yield result
+ yield b
+ return
#Decrypt if it's a block cipher
if self._readState.encContext.isBlockCipher:
@@ -1064,7 +1113,11 @@ class TLSRecordLayer(object):
def _calcPendingStates(self, cipherSuite, masterSecret,
clientRandom, serverRandom, implementations):
- if cipherSuite in CipherSuite.aes128Suites:
+ if cipherSuite in CipherSuite.aes128GcmSuites:
+ keyLength = 16
+ ivLength = 4
+ createCipherFunc = createAESGCM
+ elif cipherSuite in CipherSuite.aes128Suites:
keyLength = 16
ivLength = 16
createCipherFunc = createAES
@@ -1083,7 +1136,10 @@ class TLSRecordLayer(object):
else:
raise AssertionError()
- if cipherSuite in CipherSuite.shaSuites:
+ if cipherSuite in CipherSuite.aeadSuites:
+ macLength = 0
+ digestmod = None
+ elif cipherSuite in CipherSuite.shaSuites:
macLength = 20
digestmod = hashlib.sha1
elif cipherSuite in CipherSuite.sha256Suites:
@@ -1092,8 +1148,12 @@ class TLSRecordLayer(object):
elif cipherSuite in CipherSuite.md5Suites:
macLength = 16
digestmod = hashlib.md5
+ else:
+ raise AssertionError()
- if self.version == (3,0):
+ if not digestmod:
+ createMACFunc = None
+ elif self.version == (3,0):
createMACFunc = createMAC_SSL
elif self.version in ((3,1), (3,2), (3,3)):
createMACFunc = createHMAC
@@ -1128,16 +1188,28 @@ class TLSRecordLayer(object):
serverKeyBlock = p.getFixBytes(keyLength)
clientIVBlock = p.getFixBytes(ivLength)
serverIVBlock = p.getFixBytes(ivLength)
- clientPendingState.macContext = createMACFunc(
- compatHMAC(clientMACBlock), digestmod=digestmod)
- serverPendingState.macContext = createMACFunc(
- compatHMAC(serverMACBlock), digestmod=digestmod)
- clientPendingState.encContext = createCipherFunc(clientKeyBlock,
- clientIVBlock,
- implementations)
- serverPendingState.encContext = createCipherFunc(serverKeyBlock,
- serverIVBlock,
- implementations)
+ if digestmod:
+ # Legacy cipher.
+ clientPendingState.macContext = createMACFunc(
+ compatHMAC(clientMACBlock), digestmod=digestmod)
+ serverPendingState.macContext = createMACFunc(
+ compatHMAC(serverMACBlock), digestmod=digestmod)
+ clientPendingState.encContext = createCipherFunc(clientKeyBlock,
+ clientIVBlock,
+ implementations)
+ serverPendingState.encContext = createCipherFunc(serverKeyBlock,
+ serverIVBlock,
+ implementations)
+ else:
+ # AEAD.
+ clientPendingState.macContext = None
+ serverPendingState.macContext = None
+ clientPendingState.encContext = createCipherFunc(clientKeyBlock,
+ implementations)
+ serverPendingState.encContext = createCipherFunc(serverKeyBlock,
+ implementations)
+ clientPendingState.fixedNonce = clientIVBlock
+ serverPendingState.fixedNonce = serverIVBlock
#Assign new connection states to pending states
if self._client:

Powered by Google App Engine
This is Rietveld 408576698