1 diff --git a/third_party/tlslite/tests/tlstest.py b/third_party/tlslite/tests/tlstest.py
2 index fa1b13f..7985d23 100755
3 --- a/third_party/tlslite/tests/tlstest.py
4 +++ b/third_party/tlslite/tests/tlstest.py
5 @@ -318,9 +318,11 @@ def clientTestCmd(argv):
7 print("Test 23 - throughput test")
8 for implementation in implementations:
9 - for cipher in ["aes128", "aes256", "3des", "rc4"]:
10 + for cipher in ["aes128gcm", "aes128", "aes256", "3des", "rc4"]:
11 if cipher == "3des" and implementation not in ("openssl", "pycrypto"):
13 + if cipher == "aes128gcm" and implementation not in ("pycrypto", "python"):
16 print("Test 23:", end=' ')
17 connection = connect()
18 @@ -678,9 +680,11 @@ def serverTestCmd(argv):
20 print("Test 23 - throughput test")
21 for implementation in implementations:
22 - for cipher in ["aes128", "aes256", "3des", "rc4"]:
23 + for cipher in ["aes128gcm", "aes128", "aes256", "3des", "rc4"]:
24 if cipher == "3des" and implementation not in ("openssl", "pycrypto"):
26 + if cipher == "aes128gcm" and implementation not in ("pycrypto", "python"):
29 print("Test 23:", end=' ')
30 connection = connect()
31 diff --git a/third_party/tlslite/tlslite/constants.py b/third_party/tlslite/tlslite/constants.py
32 index 7ee70be..e5b88af 100644
33 --- a/third_party/tlslite/tlslite/constants.py
34 +++ b/third_party/tlslite/tlslite/constants.py
35 @@ -175,6 +175,9 @@ class CipherSuite:
36 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067
37 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B
39 + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C
40 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E
43 tripleDESSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
44 tripleDESSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
45 @@ -199,6 +202,10 @@ class CipherSuite:
46 aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)
47 aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
49 + aes128GcmSuites = []
50 + aes128GcmSuites.append(TLS_RSA_WITH_AES_128_GCM_SHA256)
51 + aes128GcmSuites.append(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
54 rc4Suites.append(TLS_RSA_WITH_RC4_128_SHA)
55 rc4Suites.append(TLS_RSA_WITH_RC4_128_MD5)
56 @@ -225,25 +232,35 @@ class CipherSuite:
57 sha256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)
58 sha256Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
59 sha256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
60 + sha256Suites.append(TLS_RSA_WITH_AES_128_GCM_SHA256)
61 + sha256Suites.append(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
63 + aeadSuites = aes128GcmSuites
67 md5Suites.append(TLS_RSA_WITH_RC4_128_MD5)
70 - def _filterSuites(suites, settings):
71 + def _filterSuites(suites, settings, version=None):
73 + version = settings.maxVersion
74 macNames = settings.macNames
75 cipherNames = settings.cipherNames
76 keyExchangeNames = settings.keyExchangeNames
79 macSuites += CipherSuite.shaSuites
80 - if "sha256" in macNames:
81 + if "sha256" in macNames and version >= (3,3):
82 macSuites += CipherSuite.sha256Suites
84 macSuites += CipherSuite.md5Suites
85 + if "aead" in macNames and version >= (3,3):
86 + macSuites += CipherSuite.aeadSuites
89 + if "aes128gcm" in cipherNames and version >= (3,3):
90 + cipherSuites += CipherSuite.aes128GcmSuites
91 if "aes128" in cipherNames:
92 cipherSuites += CipherSuite.aes128Suites
93 if "aes256" in cipherNames:
94 @@ -274,8 +291,8 @@ class CipherSuite:
95 srpSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
98 - def getSrpSuites(settings):
99 - return CipherSuite._filterSuites(CipherSuite.srpSuites, settings)
100 + def getSrpSuites(settings, version=None):
101 + return CipherSuite._filterSuites(CipherSuite.srpSuites, settings, version)
104 srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)
105 @@ -283,16 +300,17 @@ class CipherSuite:
106 srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
109 - def getSrpCertSuites(settings):
110 - return CipherSuite._filterSuites(CipherSuite.srpCertSuites, settings)
111 + def getSrpCertSuites(settings, version=None):
112 + return CipherSuite._filterSuites(CipherSuite.srpCertSuites, settings, version)
114 srpAllSuites = srpSuites + srpCertSuites
117 - def getSrpAllSuites(settings):
118 - return CipherSuite._filterSuites(CipherSuite.srpAllSuites, settings)
119 + def getSrpAllSuites(settings, version=None):
120 + return CipherSuite._filterSuites(CipherSuite.srpAllSuites, settings, version)
123 + certSuites.append(TLS_RSA_WITH_AES_128_GCM_SHA256)
124 certSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)
125 certSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA256)
126 certSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
127 @@ -302,10 +320,11 @@ class CipherSuite:
128 certSuites.append(TLS_RSA_WITH_RC4_128_MD5)
131 - def getCertSuites(settings):
132 - return CipherSuite._filterSuites(CipherSuite.certSuites, settings)
133 + def getCertSuites(settings, version=None):
134 + return CipherSuite._filterSuites(CipherSuite.certSuites, settings, version)
137 + dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
138 dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
139 dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
140 dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
141 @@ -313,8 +332,8 @@ class CipherSuite:
142 dheCertSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
145 - def getDheCertSuites(settings):
146 - return CipherSuite._filterSuites(CipherSuite.dheCertSuites, settings)
147 + def getDheCertSuites(settings, version=None):
148 + return CipherSuite._filterSuites(CipherSuite.dheCertSuites, settings, version)
150 certAllSuites = srpCertSuites + certSuites + dheCertSuites
152 @@ -323,8 +342,8 @@ class CipherSuite:
153 anonSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
156 - def getAnonSuites(settings):
157 - return CipherSuite._filterSuites(CipherSuite.anonSuites, settings)
158 + def getAnonSuites(settings, version=None):
159 + return CipherSuite._filterSuites(CipherSuite.anonSuites, settings, version)
161 dhAllSuites = dheCertSuites + anonSuites
163 diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py
164 index 2e9e06d..2f11aaa 100644
165 --- a/third_party/tlslite/tlslite/handshakesettings.py
166 +++ b/third_party/tlslite/tlslite/handshakesettings.py
167 @@ -11,11 +11,9 @@ from .constants import CertificateType
168 from .utils import cryptomath
169 from .utils import cipherfactory
171 -# RC4 is preferred as faster in Python, works in SSL3, and immune to CBC
172 -# issues such as timing attacks
173 -CIPHER_NAMES = ["rc4", "aes256", "aes128", "3des"]
174 -MAC_NAMES = ["sha", "sha256"] # Don't allow "md5" by default.
175 -ALL_MAC_NAMES = ["sha", "sha256", "md5"]
176 +CIPHER_NAMES = ["aes128gcm", "rc4", "aes256", "aes128", "3des"]
177 +MAC_NAMES = ["sha", "sha256", "aead"] # Don't allow "md5" by default.
178 +ALL_MAC_NAMES = MAC_NAMES + ["md5"]
179 KEY_EXCHANGE_NAMES = ["rsa", "dhe_rsa", "srp_sha", "srp_sha_rsa", "dh_anon"]
180 CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"]
181 CERTIFICATE_TYPES = ["x509"]
182 @@ -42,7 +40,7 @@ class HandshakeSettings(object):
185 @type cipherNames: list
186 - @ivar cipherNames: The allowed ciphers, in order of preference.
187 + @ivar cipherNames: The allowed ciphers.
189 The allowed values in this list are 'aes256', 'aes128', '3des', and
190 'rc4'. If these settings are used with a client handshake, they
191 @@ -68,8 +66,7 @@ class HandshakeSettings(object):
194 @type certificateTypes: list
195 - @ivar certificateTypes: The allowed certificate types, in order of
197 + @ivar certificateTypes: The allowed certificate types.
199 The only allowed certificate type is 'x509'. This list is only used with a
200 client handshake. The client will advertise to the server which certificate
201 @@ -197,10 +194,6 @@ class HandshakeSettings(object):
202 if not other.maxVersion in ((3,0), (3,1), (3,2), (3,3)):
203 raise ValueError("maxVersion set incorrectly")
205 - if other.maxVersion < (3,3):
206 - # No sha256 pre TLS 1.2
207 - other.macNames = [e for e in self.macNames if e != "sha256"]
211 def _getCertificateTypes(self):
212 diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
213 index 3d97e97..0e13a78 100644
214 --- a/third_party/tlslite/tlslite/tlsconnection.py
215 +++ b/third_party/tlslite/tlslite/tlsconnection.py
216 @@ -1385,21 +1385,6 @@ class TLSConnection(TLSRecordLayer):
218 def _serverGetClientHello(self, settings, certChain, verifierDB,
219 sessionCache, anon, fallbackSCSV):
220 - #Initialize acceptable cipher suites
225 - CipherSuite.getSrpCertSuites(settings)
226 - cipherSuites += CipherSuite.getSrpSuites(settings)
228 - cipherSuites += CipherSuite.getDheCertSuites(settings)
229 - cipherSuites += CipherSuite.getCertSuites(settings)
231 - cipherSuites += CipherSuite.getAnonSuites(settings)
235 #Tentatively set version to most-desirable version, so if an error
236 #occurs parsing the ClientHello, this is what we'll use for the
238 @@ -1451,7 +1436,22 @@ class TLSConnection(TLSRecordLayer):
241 #Set the version to the client's version
242 - self.version = clientHello.client_version
243 + self.version = clientHello.client_version
245 + #Initialize acceptable cipher suites
250 + CipherSuite.getSrpCertSuites(settings, self.version)
251 + cipherSuites += CipherSuite.getSrpSuites(settings, self.version)
253 + cipherSuites += CipherSuite.getDheCertSuites(settings, self.version)
254 + cipherSuites += CipherSuite.getCertSuites(settings, self.version)
256 + cipherSuites += CipherSuite.getAnonSuites(settings, self.version)
260 #If resumption was requested and we have a session cache...
261 if clientHello.session_id and sessionCache:
262 diff --git a/third_party/tlslite/tlslite/tlsrecordlayer.py b/third_party/tlslite/tlslite/tlsrecordlayer.py
263 index a09499d..c3bcd8c 100644
264 --- a/third_party/tlslite/tlslite/tlsrecordlayer.py
265 +++ b/third_party/tlslite/tlslite/tlsrecordlayer.py
266 @@ -11,7 +11,8 @@ from __future__ import generators
268 from .utils.compat import *
269 from .utils.cryptomath import *
270 -from .utils.cipherfactory import createAES, createRC4, createTripleDES
271 +from .utils.cipherfactory import createAESGCM, createAES, createRC4, \
273 from .utils.codec import *
274 from .errors import *
275 from .messages import *
276 @@ -592,10 +593,30 @@ class TLSRecordLayer(object):
277 if self.fault == Fault.badMAC:
278 macBytes[0] = (macBytes[0]+1) % 256
280 - #Encrypt for Block or Stream Cipher
281 + #Encrypt for non-NULL cipher.
282 if self._writeState.encContext:
284 + if self._writeState.encContext.isAEAD:
285 + #Assemble the authenticated data.
286 + seqNumBytes = self._writeState.getSeqNumBytes()
287 + authData = seqNumBytes + bytearray([contentType,
293 + #The nonce is always the fixed nonce and the sequence number.
294 + nonce = self._writeState.fixedNonce + seqNumBytes
295 + assert len(nonce) == self._writeState.encContext.nonceLength
297 + b = self._writeState.encContext.seal(nonce, b, authData)
299 + #The only AEAD supported, AES-GCM, has an explicit variable
301 + b = seqNumBytes + b
303 #Add padding and encrypt (for Block Cipher):
304 - if self._writeState.encContext.isBlockCipher:
305 + elif self._writeState.encContext.isBlockCipher:
307 #Add TLS 1.1 fixed block
308 if self.version >= (3,2):
309 @@ -967,6 +988,43 @@ class TLSRecordLayer(object):
311 def _decryptRecord(self, recordType, b):
312 if self._readState.encContext:
313 + #Open if it's an AEAD.
314 + if self._readState.encContext.isAEAD:
315 + #The only AEAD supported, AES-GCM, has an explicit variable
317 + explicitNonceLength = 8
318 + if explicitNonceLength > len(b):
320 + for result in self._sendError(
321 + AlertDescription.bad_record_mac,
322 + "MAC failure (or padding failure)"):
324 + nonce = self._readState.fixedNonce + b[:explicitNonceLength]
327 + if self._readState.encContext.tagLength > len(b):
329 + for result in self._sendError(
330 + AlertDescription.bad_record_mac,
331 + "MAC failure (or padding failure)"):
334 + #Assemble the authenticated data.
335 + seqnumBytes = self._readState.getSeqNumBytes()
336 + plaintextLen = len(b) - self._readState.encContext.tagLength
337 + authData = seqnumBytes + bytearray([recordType, self.version[0],
342 + b = self._readState.encContext.open(nonce, b, authData)
344 + for result in self._sendError(
345 + AlertDescription.bad_record_mac,
346 + "MAC failure (or padding failure)"):
351 #Decrypt if it's a block cipher
352 if self._readState.encContext.isBlockCipher:
353 @@ -1064,7 +1122,11 @@ class TLSRecordLayer(object):
355 def _calcPendingStates(self, cipherSuite, masterSecret,
356 clientRandom, serverRandom, implementations):
357 - if cipherSuite in CipherSuite.aes128Suites:
358 + if cipherSuite in CipherSuite.aes128GcmSuites:
361 + createCipherFunc = createAESGCM
362 + elif cipherSuite in CipherSuite.aes128Suites:
365 createCipherFunc = createAES
366 @@ -1083,7 +1145,10 @@ class TLSRecordLayer(object):
368 raise AssertionError()
370 - if cipherSuite in CipherSuite.shaSuites:
371 + if cipherSuite in CipherSuite.aeadSuites:
374 + elif cipherSuite in CipherSuite.shaSuites:
376 digestmod = hashlib.sha1
377 elif cipherSuite in CipherSuite.sha256Suites:
378 @@ -1092,8 +1157,12 @@ class TLSRecordLayer(object):
379 elif cipherSuite in CipherSuite.md5Suites:
381 digestmod = hashlib.md5
383 + raise AssertionError()
385 - if self.version == (3,0):
387 + createMACFunc = None
388 + elif self.version == (3,0):
389 createMACFunc = createMAC_SSL
390 elif self.version in ((3,1), (3,2), (3,3)):
391 createMACFunc = createHMAC
392 @@ -1128,16 +1197,28 @@ class TLSRecordLayer(object):
393 serverKeyBlock = p.getFixBytes(keyLength)
394 clientIVBlock = p.getFixBytes(ivLength)
395 serverIVBlock = p.getFixBytes(ivLength)
396 - clientPendingState.macContext = createMACFunc(
397 - compatHMAC(clientMACBlock), digestmod=digestmod)
398 - serverPendingState.macContext = createMACFunc(
399 - compatHMAC(serverMACBlock), digestmod=digestmod)
400 - clientPendingState.encContext = createCipherFunc(clientKeyBlock,
403 - serverPendingState.encContext = createCipherFunc(serverKeyBlock,
408 + clientPendingState.macContext = createMACFunc(
409 + compatHMAC(clientMACBlock), digestmod=digestmod)
410 + serverPendingState.macContext = createMACFunc(
411 + compatHMAC(serverMACBlock), digestmod=digestmod)
412 + clientPendingState.encContext = createCipherFunc(clientKeyBlock,
415 + serverPendingState.encContext = createCipherFunc(serverKeyBlock,
420 + clientPendingState.macContext = None
421 + serverPendingState.macContext = None
422 + clientPendingState.encContext = createCipherFunc(clientKeyBlock,
424 + serverPendingState.encContext = createCipherFunc(serverKeyBlock,
426 + clientPendingState.fixedNonce = clientIVBlock
427 + serverPendingState.fixedNonce = serverIVBlock
429 #Assign new connection states to pending states
431 diff --git a/third_party/tlslite/tlslite/utils/aes.py b/third_party/tlslite/tlslite/utils/aes.py
432 index 95afaa3..5a038fb 100644
433 --- a/third_party/tlslite/tlslite/utils/aes.py
434 +++ b/third_party/tlslite/tlslite/utils/aes.py
435 @@ -12,6 +12,7 @@ class AES(object):
437 raise AssertionError()
438 self.isBlockCipher = True
439 + self.isAEAD = False
441 self.implementation = implementation
443 @@ -31,4 +32,4 @@ class AES(object):
444 #CBC-Mode decryption, returns plaintext
445 #WARNING: *MAY* modify the input as well
446 def decrypt(self, ciphertext):
447 - assert(len(ciphertext) % 16 == 0)
448 \ No newline at end of file
449 + assert(len(ciphertext) % 16 == 0)
450 diff --git a/third_party/tlslite/tlslite/utils/aesgcm.py b/third_party/tlslite/tlslite/utils/aesgcm.py
452 index 0000000..7319c26
454 +++ b/third_party/tlslite/tlslite/utils/aesgcm.py
457 +# See the LICENSE file for legal information regarding use of this file.
459 +# GCM derived from Go's implementation in crypto/cipher.
461 +# https://golang.org/src/crypto/cipher/gcm.go
463 +# GCM works over elements of the field GF(2^128), each of which is a 128-bit
464 +# polynomial. Throughout this implementation, polynomials are represented as
465 +# Python integers with the low-order terms at the most significant bits. So a
466 +# 128-bit polynomial is an integer from 0 to 2^128-1 with the most significant
467 +# bit representing the x^0 term and the least significant bit representing the
468 +# x^127 term. This bit reversal also applies to polynomials used as indices in a
471 +from .cryptomath import bytesToNumber, numberToByteArray
473 +class AESGCM(object):
475 + AES-GCM implementation. Note: this implementation does not attempt
476 + to be side-channel resistant. It's also rather slow.
479 + def __init__(self, key, implementation, rawAesEncrypt):
480 + self.isBlockCipher = False
482 + self.nonceLength = 12
483 + self.tagLength = 16
484 + self.implementation = implementation
486 + self.name = "aes128gcm"
487 + elif len(key) == 32:
488 + self.name = "aes256gcm"
490 + raise AssertionError()
492 + self._rawAesEncrypt = rawAesEncrypt
494 + # The GCM key is AES(0).
495 + h = bytesToNumber(self._rawAesEncrypt(bytearray(16)))
497 + # Pre-compute all 4-bit multiples of h. Note that bits are reversed
498 + # because our polynomial representation places low-order terms at the
499 + # most significant bit. Thus x^0 * h = h is at index 0b1000 = 8 and
500 + # x^1 * h is at index 0b0100 = 4.
501 + self._productTable = [0] * 16
502 + self._productTable[_reverseBits(1)] = h
503 + for i in range(2, 16, 2):
504 + self._productTable[_reverseBits(i)] = \
505 + _gcmShift(self._productTable[_reverseBits(i/2)])
506 + self._productTable[_reverseBits(i+1)] = \
507 + _gcmAdd(self._productTable[_reverseBits(i)], h)
509 + def _rawAesCtrEncrypt(self, counter, inp):
511 + Encrypts (or decrypts) plaintext with AES-CTR. counter is modified.
513 + out = bytearray(len(inp))
514 + for i in range(0, len(out), 16):
515 + mask = self._rawAesEncrypt(counter)
516 + for j in range(i, min(len(out), i + 16)):
517 + out[j] = inp[j] ^ mask[j-i]
521 + def _auth(self, ciphertext, ad, tagMask):
523 + y = self._update(y, ad)
524 + y = self._update(y, ciphertext)
525 + y ^= (len(ad) << (3 + 64)) | (len(ciphertext) << 3)
527 + y ^= bytesToNumber(tagMask)
528 + return numberToByteArray(y, 16)
530 + def _update(self, y, data):
531 + for i in range(0, len(data) // 16):
532 + y ^= bytesToNumber(data[16*i:16*i+16])
534 + extra = len(data) % 16
536 + block = bytearray(16)
537 + block[:extra] = data[-extra:]
538 + y ^= bytesToNumber(block)
543 + """ Returns y*H, where H is the GCM key. """
545 + # Multiply H by y 4 bits at a time, starting with the highest power
547 + for i in range(0, 128, 4):
548 + # Multiply by x^4. The reduction for the top four terms is
550 + retHigh = ret & 0xf
552 + ret ^= (_gcmReductionTable[retHigh] << (128-16))
554 + # Add in y' * H where y' are the next four terms of y, shifted down
555 + # to the x^0..x^4. This is one of the pre-computed multiples of
556 + # H. The multiplication by x^4 shifts them back into place.
557 + ret ^= self._productTable[y & 0xf]
562 + def seal(self, nonce, plaintext, data):
564 + Encrypts and authenticates plaintext using nonce and data. Returns the
565 + ciphertext, consisting of the encrypted plaintext and tag concatenated.
568 + if len(nonce) != 12:
569 + raise ValueError("Bad nonce length")
571 + # The initial counter value is the nonce, followed by a 32-bit counter
572 + # that starts at 1. It's used to compute the tag mask.
573 + counter = bytearray(16)
574 + counter[:12] = nonce
576 + tagMask = self._rawAesEncrypt(counter)
578 + # The counter starts at 2 for the actual encryption.
580 + ciphertext = self._rawAesCtrEncrypt(counter, plaintext)
582 + tag = self._auth(ciphertext, data, tagMask)
584 + return ciphertext + tag
586 + def open(self, nonce, ciphertext, data):
588 + Decrypts and authenticates ciphertext using nonce and data. If the
589 + tag is valid, the plaintext is returned. If the tag is invalid,
593 + if len(nonce) != 12:
594 + raise ValueError("Bad nonce length")
595 + if len(ciphertext) < 16:
598 + tag = ciphertext[-16:]
599 + ciphertext = ciphertext[:-16]
601 + # The initial counter value is the nonce, followed by a 32-bit counter
602 + # that starts at 1. It's used to compute the tag mask.
603 + counter = bytearray(16)
604 + counter[:12] = nonce
606 + tagMask = self._rawAesEncrypt(counter)
608 + if tag != self._auth(ciphertext, data, tagMask):
611 + # The counter starts at 2 for the actual decryption.
613 + return self._rawAesCtrEncrypt(counter, ciphertext)
615 +def _reverseBits(i):
617 + i = ((i << 2) & 0xc) | ((i >> 2) & 0x3)
618 + i = ((i << 1) & 0xa) | ((i >> 1) & 0x5)
625 + # Multiplying by x is a right shift, due to bit order.
626 + highTermSet = x & 1
629 + # The x^127 term was shifted up to x^128, so subtract a 1+x+x^2+x^7
630 + # term. This is 0b11100001 or 0xe1 when represented as an 8-bit
632 + x ^= 0xe1 << (128-8)
635 +def _inc32(counter):
636 + for i in range(len(counter)-1, len(counter)-5, -1):
637 + counter[i] = (counter[i] + 1) % 256
638 + if counter[i] != 0:
642 +# _gcmReductionTable[i] is i * (1+x+x^2+x^7) for all 4-bit polynomials i. The
643 +# result is stored as a 16-bit polynomial. This is used in the reduction step to
644 +# multiply elements of GF(2^128) by x^4.
645 +_gcmReductionTable = [
646 + 0x0000, 0x1c20, 0x3840, 0x2460, 0x7080, 0x6ca0, 0x48c0, 0x54e0,
647 + 0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0,
649 diff --git a/third_party/tlslite/tlslite/utils/cipherfactory.py b/third_party/tlslite/tlslite/utils/cipherfactory.py
650 index 20e20f1..d525644 100644
651 --- a/third_party/tlslite/tlslite/utils/cipherfactory.py
652 +++ b/third_party/tlslite/tlslite/utils/cipherfactory.py
656 from tlslite.utils import python_aes
657 +from tlslite.utils import python_aesgcm
658 from tlslite.utils import python_rc4
660 from tlslite.utils import cryptomath
661 @@ -20,6 +21,7 @@ if cryptomath.m2cryptoLoaded:
663 if cryptomath.pycryptoLoaded:
664 from tlslite.utils import pycrypto_aes
665 + from tlslite.utils import pycrypto_aesgcm
666 from tlslite.utils import pycrypto_rc4
667 from tlslite.utils import pycrypto_tripledes
668 tripleDESPresent = True
669 @@ -52,6 +54,25 @@ def createAES(key, IV, implList=None):
670 return python_aes.new(key, 2, IV)
671 raise NotImplementedError()
673 +def createAESGCM(key, implList=None):
674 + """Create a new AESGCM object.
676 + @type key: bytearray
677 + @param key: A 16 or 32 byte byte array.
679 + @rtype: L{tlslite.utils.AESGCM}
680 + @return: An AESGCM object.
682 + if implList == None:
683 + implList = ["pycrypto", "python"]
685 + for impl in implList:
686 + if impl == "pycrypto" and cryptomath.pycryptoLoaded:
687 + return pycrypto_aesgcm.new(key)
688 + if impl == "python":
689 + return python_aesgcm.new(key)
690 + raise NotImplementedError()
692 def createRC4(key, IV, implList=None):
693 """Create a new RC4 object.
695 @@ -99,4 +120,4 @@ def createTripleDES(key, IV, implList=None):
696 return openssl_tripledes.new(key, 2, IV)
697 elif impl == "pycrypto" and cryptomath.pycryptoLoaded:
698 return pycrypto_tripledes.new(key, 2, IV)
699 - raise NotImplementedError()
700 \ No newline at end of file
701 + raise NotImplementedError()
702 diff --git a/third_party/tlslite/tlslite/utils/pycrypto_aesgcm.py b/third_party/tlslite/tlslite/utils/pycrypto_aesgcm.py
704 index 0000000..ee187ee
706 +++ b/third_party/tlslite/tlslite/utils/pycrypto_aesgcm.py
709 +# See the LICENSE file for legal information regarding use of this file.
711 +"""PyCrypto AES-GCM implementation."""
713 +from .cryptomath import *
714 +from .aesgcm import AESGCM
717 + import Crypto.Cipher.AES
720 + cipher = Crypto.Cipher.AES.new(bytes(key))
721 + def encrypt(plaintext):
722 + return bytearray(cipher.encrypt(bytes(plaintext)))
723 + return AESGCM(key, "pycrypto", encrypt)
724 diff --git a/third_party/tlslite/tlslite/utils/python_aesgcm.py b/third_party/tlslite/tlslite/utils/python_aesgcm.py
726 index 0000000..80a5fd5
728 +++ b/third_party/tlslite/tlslite/utils/python_aesgcm.py
731 +# See the LICENSE file for legal information regarding use of this file.
733 +"""Pure-Python AES-GCM implementation."""
735 +from .aesgcm import AESGCM
736 +from .rijndael import rijndael
739 + return AESGCM(key, "python", rijndael(key, 16).encrypt)
740 diff --git a/third_party/tlslite/tlslite/utils/rc4.py b/third_party/tlslite/tlslite/utils/rc4.py
741 index 809026a..3853f5b 100644
742 --- a/third_party/tlslite/tlslite/utils/rc4.py
743 +++ b/third_party/tlslite/tlslite/utils/rc4.py
744 @@ -9,6 +9,7 @@ class RC4(object):
745 if len(keyBytes) < 16 or len(keyBytes) > 256:
747 self.isBlockCipher = False
748 + self.isAEAD = False
750 self.implementation = implementation
752 @@ -16,4 +17,4 @@ class RC4(object):
753 raise NotImplementedError()
755 def decrypt(self, ciphertext):
756 - raise NotImplementedError()
757 \ No newline at end of file
758 + raise NotImplementedError()
759 diff --git a/third_party/tlslite/tlslite/utils/tripledes.py b/third_party/tlslite/tlslite/utils/tripledes.py
760 index 0b4d075..ddcdcad 100644
761 --- a/third_party/tlslite/tlslite/utils/tripledes.py
762 +++ b/third_party/tlslite/tlslite/utils/tripledes.py
763 @@ -12,6 +12,7 @@ class TripleDES(object):
766 self.isBlockCipher = True
767 + self.isAEAD = False
769 self.implementation = implementation