Skip to content

Commit

Permalink
gcm: use 96bits for mac and iv, as recommended by rfc 5048
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasWaldmann committed May 13, 2016
1 parent b6ba6b9 commit 33c6355
Showing 1 changed file with 16 additions and 16 deletions.
32 changes: 16 additions & 16 deletions borg/crypto.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ cdef class AES_CTR_256_HMAC_SHA_256_legacy:


cdef class AES_GCM_256_GMAC:
# Layout: GMAC 16 + IV 16 + CT (borg 1.2)
# Layout: GMAC 12 + IV 12 + CT (borg 1.2)
# additionally, each chunk starts with a type byte,
# which is not passed to this code or added by this code.

Expand All @@ -216,7 +216,7 @@ cdef class AES_GCM_256_GMAC:
def __cinit__(self, mac_key, enc_key, iv=None):
assert mac_key is None
assert isinstance(enc_key, bytes) and len(enc_key) == 32
assert iv is None or isinstance(iv, bytes) and len(iv) == 16
assert iv is None or isinstance(iv, bytes) and len(iv) == 12
self.enc_key = enc_key
if iv is not None:
self.iv = iv
Expand All @@ -227,13 +227,13 @@ cdef class AES_GCM_256_GMAC:

@property
def current_iv(self):
return self.ctx.iv[:16]
return self.ctx.iv[:12]

def encrypt(self, data, aad=b''):
cdef Py_buffer idata = ro_buffer(data)
cdef int ilen = len(data)
cdef int alen = len(aad)
cdef unsigned char *odata = <unsigned char *>malloc(16 + 16 + ilen + 16)
cdef unsigned char *odata = <unsigned char *>malloc(12 + 12 + ilen + 16)
cdef int olen
cdef int offset
if not odata:
Expand All @@ -244,18 +244,18 @@ cdef class AES_GCM_256_GMAC:
if not rc:
raise Exception('EVP_EncryptInit_ex failed')
# Set IV length (bytes)
if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL):
if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL):
raise Exception('EVP_CIPHER_CTX_ctrl SET IVLEN failed')
rc = EVP_EncryptInit_ex(&self.ctx, NULL, NULL, self.enc_key, self.iv)
if not rc:
raise Exception('EVP_EncryptInit_ex failed')
rc = EVP_EncryptUpdate(&self.ctx, NULL, &olen, <const unsigned char*> aad, alen)
if not rc:
raise Exception('EVP_EncryptUpdate failed')
offset = 16
if not EVP_EncryptUpdate(&self.ctx, NULL, &olen, odata+offset, 16):
offset = 12
if not EVP_EncryptUpdate(&self.ctx, NULL, &olen, odata+offset, 12):
raise Exception('EVP_EncryptUpdate failed')
offset += 16
offset += 12
rc = EVP_EncryptUpdate(&self.ctx, odata+offset, &olen, <const unsigned char*> idata.buf, ilen)
if not rc:
raise Exception('EVP_EncryptUpdate failed')
Expand All @@ -264,7 +264,7 @@ cdef class AES_GCM_256_GMAC:
if not rc:
raise Exception('EVP_EncryptFinal_ex failed')
offset += olen
if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_GET_TAG, 16, odata):
if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_GET_TAG, 12, odata):
raise Exception('EVP_CIPHER_CTX_ctrl GET TAG failed')
return odata[:offset]
finally:
Expand All @@ -285,20 +285,20 @@ cdef class AES_GCM_256_GMAC:
raise Exception('EVP_DecryptInit_ex failed')
iv = self.fetch_iv(<unsigned char *> idata.buf)
# Set IV length (bytes)
if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL):
if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL):
raise Exception('EVP_CIPHER_CTX_ctrl SET IVLEN failed')
if not EVP_DecryptInit_ex(&self.ctx, NULL, NULL, self.enc_key, iv):
raise Exception('EVP_DecryptInit_ex failed')
# Set expected tag (mac) value. Works in OpenSSL 1.0.1d and later. <-- XXX WAT!?
if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_TAG, 16, <void *> idata.buf):
if not EVP_CIPHER_CTX_ctrl(&self.ctx, EVP_CTRL_GCM_SET_TAG, 12, <void *> idata.buf):
raise Exception('EVP_CIPHER_CTX_ctrl SET TAG failed')
rc = EVP_DecryptUpdate(&self.ctx, NULL, &olen, <const unsigned char*> aad, alen)
if not rc:
raise Exception('EVP_DecryptUpdate failed')
if not EVP_DecryptUpdate(&self.ctx, NULL, &olen, <const unsigned char*> idata.buf+16, 16):
if not EVP_DecryptUpdate(&self.ctx, NULL, &olen, <const unsigned char*> idata.buf+12, 12):
raise Exception('EVP_DecryptUpdate failed')
offset = 0
rc = EVP_DecryptUpdate(&self.ctx, odata+offset, &olen, <const unsigned char*> idata.buf+32, ilen-32)
rc = EVP_DecryptUpdate(&self.ctx, odata+offset, &olen, <const unsigned char*> idata.buf+24, ilen-24)
if not rc:
raise Exception('EVP_DecryptUpdate failed')
offset += olen
Expand All @@ -315,12 +315,12 @@ cdef class AES_GCM_256_GMAC:
PyBuffer_Release(&idata)

cdef fetch_iv(self, unsigned char * idata):
return idata[16:32]
return idata[12:24]

cdef store_iv(self, unsigned char * odata, unsigned char * iv):
cdef int i
for i in range(16): # XXX easier way?
odata[16+i] = iv[i]
for i in range(12): # XXX easier way?
odata[12+i] = iv[i]


def hmac_sha256(key, data):
Expand Down

0 comments on commit 33c6355

Please sign in to comment.