diff --git a/attic/crypto.pyx b/attic/crypto.pyx index d92806f36..a087e8459 100644 --- a/attic/crypto.pyx +++ b/attic/crypto.pyx @@ -10,7 +10,7 @@ API_VERSION = 2 AES_CTR_MODE = 1 AES_GCM_MODE = 2 -TAG_SIZE = 16 # bytes; 128 bits is the maximum allowed value. see "hack" below. +MAC_SIZE = 16 # bytes; 128 bits is the maximum allowed value. see "hack" below. IV_SIZE = 16 # bytes; 128 bits cdef extern from "openssl/rand.h": @@ -159,13 +159,13 @@ cdef class AES: if not EVP_DecryptUpdate(&self.ctx, NULL, &outl, aad, aadl): raise Exception('EVP_DecryptUpdate failed') - def compute_tag_and_encrypt(self, data): + def compute_mac_and_encrypt(self, data): cdef int inl = len(data) cdef int ctl = 0 cdef int outl = 0 # note: modes that use padding, need up to one extra AES block (16B) cdef unsigned char *out = malloc(inl+16) - cdef unsigned char *tag = malloc(TAG_SIZE) + cdef unsigned char *mac = malloc(MAC_SIZE) if not out: raise MemoryError try: @@ -176,16 +176,16 @@ cdef class AES: raise Exception('EVP_EncryptFinal failed') ctl += outl if self.mode == AES_GCM_MODE: - # Get tag (only GCM mode. for CTR, the returned tag is undefined) - if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_GET_TAG, TAG_SIZE, tag): + # Get tag (mac) - only GCM mode. for CTR, the returned mac is undefined + if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_GET_TAG, MAC_SIZE, mac): raise Exception('EVP_CIPHER_CTX_ctrl GET TAG failed') # hack: caller wants 32B tags (256b), so we give back that amount - return (tag[:TAG_SIZE] + b'\x00'*16), out[:ctl] + return (mac[:MAC_SIZE] + b'\x00'*16), out[:ctl] finally: - free(tag) + free(mac) free(out) - def check_tag_and_decrypt(self, tag, data): + def check_mac_and_decrypt(self, mac, data): cdef int inl = len(data) cdef int ptl = 0 cdef int outl = 0 @@ -200,11 +200,11 @@ cdef class AES: raise Exception('EVP_DecryptUpdate failed') ptl = outl if self.mode == AES_GCM_MODE: - # Set expected tag value. - if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_TAG, TAG_SIZE, tag): + # Set expected tag (mac) value. + if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_TAG, MAC_SIZE, mac): raise Exception('EVP_CIPHER_CTX_ctrl SET TAG failed') if EVP_DecryptFinal_ex(&self.ctx, out+ptl, &outl) <= 0: - # for GCM mode, a failure here means corrupted / tampered tag or data + # for GCM mode, a failure here means corrupted / tampered tag (mac) or data raise Exception('EVP_DecryptFinal failed') ptl += outl return out[:ptl] diff --git a/attic/key.py b/attic/key.py index 5269164fa..20b88191a 100644 --- a/attic/key.py +++ b/attic/key.py @@ -111,8 +111,8 @@ class GHASH: mac_cipher = AES(mode=AES_GCM_MODE, is_encrypt=True, key=self.key, iv=b'\0' * 16) # GMAC = aes-gcm with all data as AAD, no data as to-be-encrypted data mac_cipher.add(bytes(self.data)) - tag, _ = mac_cipher.compute_tag_and_encrypt(b'') - return tag + hash, _ = mac_cipher.compute_mac_and_encrypt(b'') + return hash class HMAC_SHA256(HMAC): @@ -202,10 +202,10 @@ class PLAIN: def __init__(self, **kw): pass - def compute_tag_and_encrypt(self, data): + def compute_mac_and_encrypt(self, data): return b'', b'', data - def check_tag_and_decrypt(self, tag, iv_last8, data): + def check_mac_and_decrypt(self, mac, iv_last8, data): return data @@ -218,22 +218,22 @@ class AES_CTR_HMAC: self.enc_cipher = AES(mode=AES_CTR_MODE, is_encrypt=True, key=enc_key, iv=enc_iv) self.dec_cipher = AES(mode=AES_CTR_MODE, is_encrypt=False, key=enc_key) - def compute_tag_and_encrypt(self, data): + def compute_mac_and_encrypt(self, data): self.enc_cipher.reset(iv=self.enc_iv) iv_last8 = self.enc_iv[8:] - _, data = self.enc_cipher.compute_tag_and_encrypt(data) + _, data = self.enc_cipher.compute_mac_and_encrypt(data) # increase the IV (counter) value so same value is never used twice current_iv = bytes_to_long(iv_last8) self.enc_iv = PREFIX + long_to_bytes(current_iv + num_aes_blocks(len(data))) - tag = HMAC(self.hmac_key, iv_last8 + data, sha256).digest() # XXX mac / hash flexibility - return tag, iv_last8, data + mac = HMAC(self.hmac_key, iv_last8 + data, sha256).digest() # XXX mac / hash flexibility + return mac, iv_last8, data - def check_tag_and_decrypt(self, tag, iv_last8, data): + def check_mac_and_decrypt(self, mac, iv_last8, data): iv = PREFIX + iv_last8 - if HMAC(self.hmac_key, iv_last8 + data, sha256).digest() != tag: + if HMAC(self.hmac_key, iv_last8 + data, sha256).digest() != mac: raise IntegrityError('Encryption envelope checksum mismatch') self.dec_cipher.reset(iv=iv) - data = self.dec_cipher.check_tag_and_decrypt(None, data) + data = self.dec_cipher.check_mac_and_decrypt(None, data) return data @@ -246,22 +246,22 @@ class AES_GCM: self.enc_cipher = AES(mode=AES_GCM_MODE, is_encrypt=True, key=enc_key, iv=enc_iv) self.dec_cipher = AES(mode=AES_GCM_MODE, is_encrypt=False, key=enc_key) - def compute_tag_and_encrypt(self, data): + def compute_mac_and_encrypt(self, data): self.enc_cipher.reset(iv=self.enc_iv) iv_last8 = self.enc_iv[8:] self.enc_cipher.add(iv_last8) - tag, data = self.enc_cipher.compute_tag_and_encrypt(data) + mac, data = self.enc_cipher.compute_mac_and_encrypt(data) # increase the IV (counter) value so same value is never used twice current_iv = bytes_to_long(iv_last8) self.enc_iv = PREFIX + long_to_bytes(current_iv + num_aes_blocks(len(data))) - return tag, iv_last8, data + return mac, iv_last8, data - def check_tag_and_decrypt(self, tag, iv_last8, data): + def check_mac_and_decrypt(self, mac, iv_last8, data): iv = PREFIX + iv_last8 self.dec_cipher.reset(iv=iv) self.dec_cipher.add(iv_last8) try: - data = self.dec_cipher.check_tag_and_decrypt(tag, data) + data = self.dec_cipher.check_mac_and_decrypt(mac, data) except Exception: raise IntegrityError('Encryption envelope checksum mismatch') return data @@ -300,7 +300,7 @@ class KeyBase(object): def encrypt(self, data): data = self.compressor.compress(data) - mac, iv_last8, data = self.cipher.compute_tag_and_encrypt(data) + mac, iv_last8, data = self.cipher.compute_mac_and_encrypt(data) meta = Meta(compr_type=self.compressor.TYPE, key_type=self.TYPE, mac_type=self.maccer_cls.TYPE, cipher_type=self.cipher.TYPE, stored_iv=iv_last8) @@ -312,7 +312,7 @@ class KeyBase(object): assert isinstance(self, keyer) assert self.maccer_cls is maccer assert self.cipher_cls is cipher - data = self.cipher.check_tag_and_decrypt(mac, meta.stored_iv, data) + data = self.cipher.check_mac_and_decrypt(mac, meta.stored_iv, data) data = self.compressor.decompress(data) if id and self.id_hash(data) != id: raise IntegrityError('Chunk id verification failed') @@ -486,7 +486,7 @@ class KeyfileKey(AESKeyBase): key = pbkdf2_sha256(passphrase.encode('utf-8'), d[b'salt'], d[b'iterations'], 32) try: cipher = AES(mode=AES_GCM_MODE, is_encrypt=False, key=key, iv=b'\0'*16) - data = cipher.check_tag_and_decrypt(d[b'hash'], d[b'data']) + data = cipher.check_mac_and_decrypt(d[b'hash'], d[b'data']) return data except Exception: return None @@ -496,13 +496,13 @@ class KeyfileKey(AESKeyBase): iterations = 100000 key = pbkdf2_sha256(passphrase.encode('utf-8'), salt, iterations, 32) cipher = AES(mode=AES_GCM_MODE, is_encrypt=True, key=key, iv=b'\0'*16) - tag, cdata = cipher.compute_tag_and_encrypt(data) + mac, cdata = cipher.compute_mac_and_encrypt(data) d = { 'version': 1, 'salt': salt, 'iterations': iterations, 'algorithm': 'gmac', - 'hash': tag, + 'hash': mac, 'data': cdata, } return msgpack.packb(d) @@ -655,7 +655,7 @@ def parser02(all_data): def parser03(all_data): # new & flexible """ Payload layout: - always: TYPE(1) + MSGPACK((tag, meta, data)) + always: TYPE(1) + MSGPACK((mac, meta, data)) meta is a Meta namedtuple and contains all required information about data. data is maybe compressed (see meta) and maybe encrypted (see meta). diff --git a/attic/testsuite/crypto.py b/attic/testsuite/crypto.py index 97cc065ca..8b523494e 100644 --- a/attic/testsuite/crypto.py +++ b/attic/testsuite/crypto.py @@ -34,11 +34,11 @@ class CryptoTestCase(AtticTestCase): data = b'foo' * 10 # encrypt aes = AES(mode=AES_CTR_MODE, is_encrypt=True, key=key, iv=iv) - _, cdata = aes.compute_tag_and_encrypt(data) + _, cdata = aes.compute_mac_and_encrypt(data) self.assert_equal(hexlify(cdata), b'c6efb702de12498f34a2c2bbc8149e759996d08bf6dc5c610aefc0c3a466') - # decrypt (correct tag/cdata) + # decrypt (correct mac/cdata) aes = AES(mode=AES_CTR_MODE, is_encrypt=False, key=key, iv=iv) - pdata = aes.check_tag_and_decrypt(None, cdata) + pdata = aes.check_mac_and_decrypt(None, cdata) self.assert_equal(data, pdata) def test_aes_gcm(self): @@ -47,14 +47,14 @@ class CryptoTestCase(AtticTestCase): data = b'foo' * 10 # encrypt aes = AES(mode=AES_GCM_MODE, is_encrypt=True, key=key, iv=iv) - tag, cdata = aes.compute_tag_and_encrypt(data) - self.assert_equal(hexlify(tag), b'c98aa10eb6b7031bcc2160878d9438fb00000000000000000000000000000000') + mac, cdata = aes.compute_mac_and_encrypt(data) + self.assert_equal(hexlify(mac), b'c98aa10eb6b7031bcc2160878d9438fb00000000000000000000000000000000') self.assert_equal(hexlify(cdata), b'841bcce405df769d22ee9f7f012edf5dc7fb2594d924c7400ffd050f2741') - # decrypt (correct tag/cdata) + # decrypt (correct mac/cdata) aes = AES(mode=AES_GCM_MODE, is_encrypt=False, key=key, iv=iv) - pdata = aes.check_tag_and_decrypt(tag, cdata) + pdata = aes.check_mac_and_decrypt(mac, cdata) self.assert_equal(data, pdata) - # decrypt (incorrect tag/cdata) + # decrypt (incorrect mac/cdata) aes = AES(mode=AES_GCM_MODE, is_encrypt=False, key=key, iv=iv) cdata = b'x' + cdata[1:] # corrupt cdata - self.assertRaises(Exception, aes.check_tag_and_decrypt, tag, cdata) + self.assertRaises(Exception, aes.check_mac_and_decrypt, mac, cdata)