Skip to content
Snippets Groups Projects
Commit a9a13eb2 authored by Guillaume Valadon's avatar Guillaume Valadon
Browse files

Merge pull request #53 from kinap/master

Added AEAD digest support to IPSec layer, specifically for GCM and CC…
parents ce58503f 833f93b3
No related branches found
No related tags found
No related merge requests found
......@@ -40,6 +40,7 @@ True
"""
import socket
import struct
from Crypto.Util.number import GCD as gcd
from scapy.data import IP_PROTOS
......@@ -169,7 +170,7 @@ class CryptAlgo(object):
IPSec encryption algorithm
"""
def __init__(self, name, cipher, mode, block_size=None, iv_size=None, key_size=None):
def __init__(self, name, cipher, mode, block_size=None, iv_size=None, key_size=None, icv_size=None):
"""
@param name: the name of this encryption algorithm
@param cipher: a Cipher module
......@@ -185,6 +186,11 @@ class CryptAlgo(object):
self.name = name
self.cipher = cipher
self.mode = mode
self.icv_size = icv_size
self.is_aead = (hasattr(self.cipher, 'MODE_GCM') and
self.mode == self.cipher.MODE_GCM) or \
(hasattr(self.cipher, 'MODE_CCM') and
self.mode == self.cipher.MODE_CCM)
if block_size is not None:
self.block_size = block_size
......@@ -232,8 +238,7 @@ class CryptAlgo(object):
@return: an initialized cipher object for this algo
"""
if (hasattr(self.cipher, 'MODE_CTR') and self.mode == self.cipher.MODE_CTR
or hasattr(self.cipher, 'MODE_GCM') and self.mode == self.cipher.MODE_GCM
or hasattr(self.cipher, 'MODE_CCM') and self.mode == self.cipher.MODE_CCM):
or self.is_aead):
# in counter mode, the "iv" must be incremented for each block
# it is calculated like this:
# +---------+------------------+---------+
......@@ -252,8 +257,7 @@ class CryptAlgo(object):
# <--------->
# nonce_size
cipher_key, nonce = key[:-nonce_size], key[-nonce_size:]
if (hasattr(self.cipher, 'MODE_GCM') and self.mode == self.cipher.MODE_GCM
or hasattr(self.cipher, 'MODE_CCM') and self.mode == self.cipher.MODE_CCM):
if self.is_aead:
return self.cipher.new(cipher_key, self.mode, nonce + iv,
counter=Counter.new(4 * 8, prefix=nonce + iv))
......@@ -307,7 +311,13 @@ class CryptAlgo(object):
if self.cipher:
self.check_key(key)
cipher = self.new_cipher(key, esp.iv)
data = cipher.encrypt(data)
if self.is_aead:
cipher.update(struct.pack('!LL', esp.spi, esp.seq))
data = cipher.encrypt(data)
data += cipher.digest()[:self.icv_size]
else:
data = cipher.encrypt(data)
return ESP(spi=esp.spi, seq=esp.seq, data=esp.iv + data)
......@@ -323,12 +333,19 @@ class CryptAlgo(object):
"""
self.check_key(key)
if self.cipher and self.is_aead:
icv_size = self.icv_size
iv = esp.data[:self.iv_size]
data = esp.data[self.iv_size:len(esp.data) - icv_size]
icv = esp.data[len(esp.data) - icv_size:]
if self.cipher:
cipher = self.new_cipher(key, iv)
if self.is_aead:
cipher.update(struct.pack('!LL', esp.spi, esp.seq))
data = cipher.decrypt(data)
# extract padlen and nh
......@@ -373,12 +390,14 @@ if AES:
cipher=AES,
mode=AES.MODE_GCM,
iv_size=8,
icv_size=8,
key_size=(16 + 4, 24 + 4, 32 + 4))
if hasattr(AES, "MODE_CCM"):
CRYPT_ALGOS['AES-CCM'] = CryptAlgo('AES-CCM',
cipher=AES,
mode=AES.MODE_CCM,
iv_size=8,
icv_size=8,
key_size=(16 + 4, 24 + 4, 32 + 4))
if DES:
CRYPT_ALGOS['DES'] = CryptAlgo('DES',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment