cosmetic: s/tag/mac/

mac is a more specific term, tag is too general

of course it is only a real MAC if we have keys, otherwise it is a hash.
This commit is contained in:
Thomas Waldmann 2015-03-22 21:27:25 +01:00
parent add6bd96e7
commit 3149f6a828
3 changed files with 42 additions and 42 deletions

View file

@ -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 = <unsigned char *>malloc(inl+16)
cdef unsigned char *tag = <unsigned char *>malloc(TAG_SIZE)
cdef unsigned char *mac = <unsigned char *>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]

View file

@ -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).

View file

@ -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)