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

Side by Side 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 unified diff | Download patch
OLDNEW
1 # Authors: 1 # Authors:
2 # Trevor Perrin 2 # Trevor Perrin
3 # Google (adapted by Sam Rushing) - NPN support 3 # Google (adapted by Sam Rushing) - NPN support
4 # Martin von Loewis - python 3 port 4 # Martin von Loewis - python 3 port
5 # Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2 5 # Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
6 # 6 #
7 # See the LICENSE file for legal information regarding use of this file. 7 # See the LICENSE file for legal information regarding use of this file.
8 8
9 """Helper class for TLSConnection.""" 9 """Helper class for TLSConnection."""
10 from __future__ import generators 10 from __future__ import generators
11 11
12 from .utils.compat import * 12 from .utils.compat import *
13 from .utils.cryptomath import * 13 from .utils.cryptomath import *
14 from .utils.cipherfactory import createAES, createRC4, createTripleDES 14 from .utils.cipherfactory import createAESGCM, createAES, createRC4, \
15 createTripleDES
15 from .utils.codec import * 16 from .utils.codec import *
16 from .errors import * 17 from .errors import *
17 from .messages import * 18 from .messages import *
18 from .mathtls import * 19 from .mathtls import *
19 from .constants import * 20 from .constants import *
20 from .utils.cryptomath import getRandomBytes 21 from .utils.cryptomath import getRandomBytes
21 22
22 import socket 23 import socket
23 import struct 24 import struct
24 import errno 25 import errno
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 mac.update(compatHMAC( bytearray([self.version[1]] ))) 586 mac.update(compatHMAC( bytearray([self.version[1]] )))
586 mac.update( compatHMAC( bytearray([len(b)//256] ))) 587 mac.update( compatHMAC( bytearray([len(b)//256] )))
587 mac.update( compatHMAC( bytearray([len(b)%256] ))) 588 mac.update( compatHMAC( bytearray([len(b)%256] )))
588 else: 589 else:
589 raise AssertionError() 590 raise AssertionError()
590 mac.update(compatHMAC(b)) 591 mac.update(compatHMAC(b))
591 macBytes = bytearray(mac.digest()) 592 macBytes = bytearray(mac.digest())
592 if self.fault == Fault.badMAC: 593 if self.fault == Fault.badMAC:
593 macBytes[0] = (macBytes[0]+1) % 256 594 macBytes[0] = (macBytes[0]+1) % 256
594 595
595 #Encrypt for Block or Stream Cipher 596 #Encrypt for Block or Stream Cipher
Ryan Sleevi 2015/01/29 20:50:48 comment update?
davidben 2015/01/29 21:40:59 Done.
596 if self._writeState.encContext: 597 if self._writeState.encContext:
598 #Seal (for AEAD)
599 if self._writeState.encContext.isAEAD:
600 #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.
601 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.
602 ad = seqnumBytes + bytearray([contentType, self.version[0],
603 self.version[1], len(b)//256,
604 len(b)%256])
605
606 #The nonce is always the fixed nonce and the sequence number.
607 nonce = self._writeState.fixedNonce + seqnumBytes
608 assert len(nonce) == self._writeState.encContext.nonceLength
609
610 b = self._writeState.encContext.seal(nonce, b, ad)
611
612 #The only AEAD supported, AES-GCM, has an explicit variable
613 #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
614 b = seqnumBytes + b
615
597 #Add padding and encrypt (for Block Cipher): 616 #Add padding and encrypt (for Block Cipher):
598 if self._writeState.encContext.isBlockCipher: 617 elif self._writeState.encContext.isBlockCipher:
599 618
600 #Add TLS 1.1 fixed block 619 #Add TLS 1.1 fixed block
601 if self.version >= (3,2): 620 if self.version >= (3,2):
602 b = self.fixedIVBlock + b 621 b = self.fixedIVBlock + b
603 622
604 #Add padding: b = b+ (macBytes + paddingBytes) 623 #Add padding: b = b+ (macBytes + paddingBytes)
605 currentLength = len(b) + len(macBytes) 624 currentLength = len(b) + len(macBytes)
606 blockLength = self._writeState.encContext.block_size 625 blockLength = self._writeState.encContext.block_size
607 paddingLength = blockLength - 1 - (currentLength % blockLength) 626 paddingLength = blockLength - 1 - (currentLength % blockLength)
608 627
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 979
961 #We've moved at least one handshake message into the 980 #We've moved at least one handshake message into the
962 #handshakeBuffer, return the first one 981 #handshakeBuffer, return the first one
963 recordHeader, b = self._handshakeBuffer[0] 982 recordHeader, b = self._handshakeBuffer[0]
964 self._handshakeBuffer = self._handshakeBuffer[1:] 983 self._handshakeBuffer = self._handshakeBuffer[1:]
965 yield (recordHeader, Parser(b)) 984 yield (recordHeader, Parser(b))
966 985
967 986
968 def _decryptRecord(self, recordType, b): 987 def _decryptRecord(self, recordType, b):
969 if self._readState.encContext: 988 if self._readState.encContext:
989 #Open if it's an AEAD.
990 if self._readState.encContext.isAEAD:
991 #The only AEAD supported, AES-GCM, has an explicit variable
992 #nonce.
993 explicitNonceLength = 8
994 if explicitNonceLength > len(b):
995 #Publicly invalid.
996 for result in self._sendError(
997 AlertDescription.bad_record_mac,
998 "MAC failure (or padding failure)"):
999 yield result
1000 nonce = self._readState.fixedNonce + b[:explicitNonceLength]
1001 b = b[8:]
1002
1003 #Assemble the AD.
1004 seqnumBytes = self._readState.getSeqNumBytes()
1005 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
1006 ad = seqnumBytes + bytearray([recordType, self.version[0],
1007 self.version[1],
1008 plaintextLen//256,
1009 plaintextLen%256])
1010
1011 b = self._readState.encContext.open(nonce, b, ad)
1012 if b is None:
1013 for result in self._sendError(
1014 AlertDescription.bad_record_mac,
1015 "MAC failure (or padding failure)"):
1016 yield result
1017 yield b
1018 return
970 1019
971 #Decrypt if it's a block cipher 1020 #Decrypt if it's a block cipher
972 if self._readState.encContext.isBlockCipher: 1021 if self._readState.encContext.isBlockCipher:
973 blockLength = self._readState.encContext.block_size 1022 blockLength = self._readState.encContext.block_size
974 if len(b) % blockLength != 0: 1023 if len(b) % blockLength != 0:
975 for result in self._sendError(\ 1024 for result in self._sendError(\
976 AlertDescription.decryption_failed, 1025 AlertDescription.decryption_failed,
977 "Encrypted data not a multiple of blocksize"): 1026 "Encrypted data not a multiple of blocksize"):
978 yield result 1027 yield result
979 b = self._readState.encContext.decrypt(b) 1028 b = self._readState.encContext.decrypt(b)
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 self._handshakeBuffer = [] 1106 self._handshakeBuffer = []
1058 self.allegedSrpUsername = None 1107 self.allegedSrpUsername = None
1059 self._refCount = 1 1108 self._refCount = 1
1060 1109
1061 def _handshakeDone(self, resumed): 1110 def _handshakeDone(self, resumed):
1062 self.resumed = resumed 1111 self.resumed = resumed
1063 self.closed = False 1112 self.closed = False
1064 1113
1065 def _calcPendingStates(self, cipherSuite, masterSecret, 1114 def _calcPendingStates(self, cipherSuite, masterSecret,
1066 clientRandom, serverRandom, implementations): 1115 clientRandom, serverRandom, implementations):
1067 if cipherSuite in CipherSuite.aes128Suites: 1116 if cipherSuite in CipherSuite.aes128GcmSuites:
1117 keyLength = 16
1118 ivLength = 4
1119 createCipherFunc = createAESGCM
1120 elif cipherSuite in CipherSuite.aes128Suites:
1068 keyLength = 16 1121 keyLength = 16
1069 ivLength = 16 1122 ivLength = 16
1070 createCipherFunc = createAES 1123 createCipherFunc = createAES
1071 elif cipherSuite in CipherSuite.aes256Suites: 1124 elif cipherSuite in CipherSuite.aes256Suites:
1072 keyLength = 32 1125 keyLength = 32
1073 ivLength = 16 1126 ivLength = 16
1074 createCipherFunc = createAES 1127 createCipherFunc = createAES
1075 elif cipherSuite in CipherSuite.rc4Suites: 1128 elif cipherSuite in CipherSuite.rc4Suites:
1076 keyLength = 16 1129 keyLength = 16
1077 ivLength = 0 1130 ivLength = 0
1078 createCipherFunc = createRC4 1131 createCipherFunc = createRC4
1079 elif cipherSuite in CipherSuite.tripleDESSuites: 1132 elif cipherSuite in CipherSuite.tripleDESSuites:
1080 keyLength = 24 1133 keyLength = 24
1081 ivLength = 8 1134 ivLength = 8
1082 createCipherFunc = createTripleDES 1135 createCipherFunc = createTripleDES
1083 else: 1136 else:
1084 raise AssertionError() 1137 raise AssertionError()
1085 1138
1086 if cipherSuite in CipherSuite.shaSuites: 1139 if cipherSuite in CipherSuite.aeadSuites:
1140 macLength = 0
1141 digestmod = None
1142 elif cipherSuite in CipherSuite.shaSuites:
1087 macLength = 20 1143 macLength = 20
1088 digestmod = hashlib.sha1 1144 digestmod = hashlib.sha1
1089 elif cipherSuite in CipherSuite.sha256Suites: 1145 elif cipherSuite in CipherSuite.sha256Suites:
1090 macLength = 32 1146 macLength = 32
1091 digestmod = hashlib.sha256 1147 digestmod = hashlib.sha256
1092 elif cipherSuite in CipherSuite.md5Suites: 1148 elif cipherSuite in CipherSuite.md5Suites:
1093 macLength = 16 1149 macLength = 16
1094 digestmod = hashlib.md5 1150 digestmod = hashlib.md5
1151 else:
1152 raise AssertionError()
1095 1153
1096 if self.version == (3,0): 1154 if not digestmod:
1155 createMACFunc = None
1156 elif self.version == (3,0):
1097 createMACFunc = createMAC_SSL 1157 createMACFunc = createMAC_SSL
1098 elif self.version in ((3,1), (3,2), (3,3)): 1158 elif self.version in ((3,1), (3,2), (3,3)):
1099 createMACFunc = createHMAC 1159 createMACFunc = createHMAC
1100 1160
1101 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2) 1161 outputLength = (macLength*2) + (keyLength*2) + (ivLength*2)
1102 1162
1103 #Calculate Keying Material from Master Secret 1163 #Calculate Keying Material from Master Secret
1104 if self.version == (3,0): 1164 if self.version == (3,0):
1105 keyBlock = PRF_SSL(masterSecret, 1165 keyBlock = PRF_SSL(masterSecret,
1106 serverRandom + clientRandom, 1166 serverRandom + clientRandom,
(...skipping 14 matching lines...) Expand all
1121 #Slice up Keying Material 1181 #Slice up Keying Material
1122 clientPendingState = _ConnectionState() 1182 clientPendingState = _ConnectionState()
1123 serverPendingState = _ConnectionState() 1183 serverPendingState = _ConnectionState()
1124 p = Parser(keyBlock) 1184 p = Parser(keyBlock)
1125 clientMACBlock = p.getFixBytes(macLength) 1185 clientMACBlock = p.getFixBytes(macLength)
1126 serverMACBlock = p.getFixBytes(macLength) 1186 serverMACBlock = p.getFixBytes(macLength)
1127 clientKeyBlock = p.getFixBytes(keyLength) 1187 clientKeyBlock = p.getFixBytes(keyLength)
1128 serverKeyBlock = p.getFixBytes(keyLength) 1188 serverKeyBlock = p.getFixBytes(keyLength)
1129 clientIVBlock = p.getFixBytes(ivLength) 1189 clientIVBlock = p.getFixBytes(ivLength)
1130 serverIVBlock = p.getFixBytes(ivLength) 1190 serverIVBlock = p.getFixBytes(ivLength)
1131 clientPendingState.macContext = createMACFunc( 1191 if digestmod:
1132 compatHMAC(clientMACBlock), digestmod=digestmod) 1192 # Legacy cipher.
1133 serverPendingState.macContext = createMACFunc( 1193 clientPendingState.macContext = createMACFunc(
1134 compatHMAC(serverMACBlock), digestmod=digestmod) 1194 compatHMAC(clientMACBlock), digestmod=digestmod)
1135 clientPendingState.encContext = createCipherFunc(clientKeyBlock, 1195 serverPendingState.macContext = createMACFunc(
1136 clientIVBlock, 1196 compatHMAC(serverMACBlock), digestmod=digestmod)
1137 implementations) 1197 clientPendingState.encContext = createCipherFunc(clientKeyBlock,
1138 serverPendingState.encContext = createCipherFunc(serverKeyBlock, 1198 clientIVBlock,
1139 serverIVBlock, 1199 implementations)
1140 implementations) 1200 serverPendingState.encContext = createCipherFunc(serverKeyBlock,
1201 serverIVBlock,
1202 implementations)
1203 else:
1204 # AEAD.
1205 clientPendingState.macContext = None
1206 serverPendingState.macContext = None
1207 clientPendingState.encContext = createCipherFunc(clientKeyBlock,
1208 implementations)
1209 serverPendingState.encContext = createCipherFunc(serverKeyBlock,
1210 implementations)
1211 clientPendingState.fixedNonce = clientIVBlock
1212 serverPendingState.fixedNonce = serverIVBlock
1141 1213
1142 #Assign new connection states to pending states 1214 #Assign new connection states to pending states
1143 if self._client: 1215 if self._client:
1144 self._pendingWriteState = clientPendingState 1216 self._pendingWriteState = clientPendingState
1145 self._pendingReadState = serverPendingState 1217 self._pendingReadState = serverPendingState
1146 else: 1218 else:
1147 self._pendingWriteState = serverPendingState 1219 self._pendingWriteState = serverPendingState
1148 self._pendingReadState = clientPendingState 1220 self._pendingReadState = clientPendingState
1149 1221
1150 if self.version >= (3,2) and ivLength: 1222 if self.version >= (3,2) and ivLength:
(...skipping 17 matching lines...) Expand all
1168 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48))) 1240 imac_md5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48)))
1169 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40))) 1241 imac_sha.update(compatHMAC(label + masterSecret + bytearray([0x36]*40)))
1170 1242
1171 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \ 1243 md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \
1172 bytearray(imac_md5.digest())) 1244 bytearray(imac_md5.digest()))
1173 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \ 1245 shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \
1174 bytearray(imac_sha.digest())) 1246 bytearray(imac_sha.digest()))
1175 1247
1176 return md5Bytes + shaBytes 1248 return md5Bytes + shaBytes
1177 1249
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698