Added support for AES CCM.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
#include "mbedtls/asn1.h"
|
#include "mbedtls/asn1.h"
|
||||||
#include "mbedtls/cipher.h"
|
#include "mbedtls/cipher.h"
|
||||||
#include "mbedtls/oid.h"
|
#include "mbedtls/oid.h"
|
||||||
|
#include "mbedtls/ccm.h"
|
||||||
|
|
||||||
/* This is copied from pkcs5.c Mbedtls */
|
/* This is copied from pkcs5.c Mbedtls */
|
||||||
/** Unfortunately it is declared as static, so I cannot call it. **/
|
/** Unfortunately it is declared as static, so I cannot call it. **/
|
||||||
@@ -577,6 +578,51 @@ int cmd_cipher_sym() {
|
|||||||
}
|
}
|
||||||
res_APDU_size = enc_len;
|
res_APDU_size = enc_len;
|
||||||
}
|
}
|
||||||
|
else if (aes_algo == 0x07 || aes_algo == 0x1B || aes_algo == 0x2F) { /* CCM */
|
||||||
|
mbedtls_aes_free(&ctx); // No AES ctx used
|
||||||
|
mbedtls_ccm_context gctx;
|
||||||
|
mbedtls_ccm_init(&gctx);
|
||||||
|
r = mbedtls_ccm_setkey(&gctx, MBEDTLS_CIPHER_ID_AES, kdata, key_size * 8);
|
||||||
|
if (r != 0) {
|
||||||
|
return SW_EXEC_ERROR();
|
||||||
|
}
|
||||||
|
if (iv_len == 16) {
|
||||||
|
iv_len = 12;
|
||||||
|
}
|
||||||
|
mbedtls_platform_zeroize(kdata, sizeof(kdata));
|
||||||
|
if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
|
||||||
|
r = mbedtls_ccm_encrypt_and_tag(&gctx,
|
||||||
|
enc_len,
|
||||||
|
iv,
|
||||||
|
iv_len,
|
||||||
|
aad,
|
||||||
|
aad_len,
|
||||||
|
enc,
|
||||||
|
res_APDU,
|
||||||
|
res_APDU + enc_len,
|
||||||
|
16);
|
||||||
|
res_APDU_size = enc_len + 16;
|
||||||
|
}
|
||||||
|
else if (algo == ALGO_EXT_CIPHER_DECRYPT) {
|
||||||
|
r = mbedtls_ccm_auth_decrypt(&gctx,
|
||||||
|
enc_len - 16,
|
||||||
|
iv,
|
||||||
|
iv_len,
|
||||||
|
aad,
|
||||||
|
aad_len,
|
||||||
|
enc,
|
||||||
|
res_APDU,
|
||||||
|
enc + enc_len - 16,
|
||||||
|
16);
|
||||||
|
res_APDU_size = enc_len - 16;
|
||||||
|
}
|
||||||
|
mbedtls_ccm_free(&gctx);
|
||||||
|
printf("r %d\n", r);
|
||||||
|
if (r != 0)
|
||||||
|
{
|
||||||
|
return SW_EXEC_ERROR();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (memcmp(oid, OID_IEEE_ALG, 8) == 0) {
|
else if (memcmp(oid, OID_IEEE_ALG, 8) == 0) {
|
||||||
if (oid_len != 9) {
|
if (oid_len != 9) {
|
||||||
|
|||||||
@@ -151,18 +151,21 @@
|
|||||||
#define OID_AES128_OFB OID_NIST_AES "\x03"
|
#define OID_AES128_OFB OID_NIST_AES "\x03"
|
||||||
#define OID_AES128_CFB OID_NIST_AES "\x04"
|
#define OID_AES128_CFB OID_NIST_AES "\x04"
|
||||||
#define OID_AES128_GCM OID_NIST_AES "\x06"
|
#define OID_AES128_GCM OID_NIST_AES "\x06"
|
||||||
|
#define OID_AES128_CCM OID_NIST_AES "\x07"
|
||||||
#define OID_AES128_CTR OID_NIST_AES "\x09" // Not existing
|
#define OID_AES128_CTR OID_NIST_AES "\x09" // Not existing
|
||||||
#define OID_AES192_ECB OID_NIST_AES "\x15"
|
#define OID_AES192_ECB OID_NIST_AES "\x15"
|
||||||
#define OID_AES192_CBC OID_NIST_AES "\x16"
|
#define OID_AES192_CBC OID_NIST_AES "\x16"
|
||||||
#define OID_AES192_OFB OID_NIST_AES "\x17"
|
#define OID_AES192_OFB OID_NIST_AES "\x17"
|
||||||
#define OID_AES192_CFB OID_NIST_AES "\x18"
|
#define OID_AES192_CFB OID_NIST_AES "\x18"
|
||||||
#define OID_AES192_GCM OID_NIST_AES "\x1A"
|
#define OID_AES192_GCM OID_NIST_AES "\x1A"
|
||||||
|
#define OID_AES192_CCM OID_NIST_AES "\x1B"
|
||||||
#define OID_AES192_CTR OID_NIST_AES "\x1D" // Not existing
|
#define OID_AES192_CTR OID_NIST_AES "\x1D" // Not existing
|
||||||
#define OID_AES256_ECB OID_NIST_AES "\x29"
|
#define OID_AES256_ECB OID_NIST_AES "\x29"
|
||||||
#define OID_AES256_CBC OID_NIST_AES "\x2A"
|
#define OID_AES256_CBC OID_NIST_AES "\x2A"
|
||||||
#define OID_AES256_OFB OID_NIST_AES "\x2B"
|
#define OID_AES256_OFB OID_NIST_AES "\x2B"
|
||||||
#define OID_AES256_CFB OID_NIST_AES "\x2C"
|
#define OID_AES256_CFB OID_NIST_AES "\x2C"
|
||||||
#define OID_AES256_GCM OID_NIST_AES "\x2E"
|
#define OID_AES256_GCM OID_NIST_AES "\x2E"
|
||||||
|
#define OID_AES256_CCM OID_NIST_AES "\x2F"
|
||||||
#define OID_AES256_CTR OID_NIST_AES "\x31" // Not existing
|
#define OID_AES256_CTR OID_NIST_AES "\x31" // Not existing
|
||||||
|
|
||||||
#define OID_IEEE_ALG "\x2B\x6F\x02\x8C\x53\x00\x00\x01"
|
#define OID_IEEE_ALG "\x2B\x6F\x02\x8C\x53\x00\x00\x01"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import os
|
import os
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes, aead
|
||||||
import cryptography.exceptions
|
import cryptography.exceptions
|
||||||
from picohsm import APDUResponse, DOPrefixes, EncryptionMode, SWCodes, AES
|
from picohsm import APDUResponse, DOPrefixes, EncryptionMode, SWCodes, AES
|
||||||
from picohsm.const import DEFAULT_DKEK_SHARES
|
from picohsm.const import DEFAULT_DKEK_SHARES
|
||||||
@@ -299,3 +299,44 @@ def test_aes_ctr_iv(device, size):
|
|||||||
assert(dtA == dtB)
|
assert(dtA == dtB)
|
||||||
assert(dtA == MESSAGE)
|
assert(dtA == MESSAGE)
|
||||||
device.delete_key(keyid)
|
device.delete_key(keyid)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"size", [128, 192, 256]
|
||||||
|
)
|
||||||
|
def test_aes_ccm_no_iv(device, size):
|
||||||
|
pkey, keyid = generate_key(device, size)
|
||||||
|
ctA = device.aes(keyid, EncryptionMode.ENCRYPT, AES.CCM, MESSAGE, aad=AAD)
|
||||||
|
|
||||||
|
iv = b'\x00' * 12
|
||||||
|
encryptor = aead.AESCCM(pkey)
|
||||||
|
ctB = encryptor.encrypt(iv, MESSAGE, AAD)
|
||||||
|
assert(ctA == ctB)
|
||||||
|
|
||||||
|
dtA = device.aes(keyid, EncryptionMode.DECRYPT, AES.CCM, ctA, aad=AAD)
|
||||||
|
decryptor = encryptor
|
||||||
|
dtB = decryptor.decrypt(iv, ctB, AAD)
|
||||||
|
assert(dtA == dtB)
|
||||||
|
assert(dtA == MESSAGE)
|
||||||
|
device.delete_key(keyid)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"size", [128, 192, 256]
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"iv_len", [7, 8, 9, 10, 11, 12, 13]
|
||||||
|
)
|
||||||
|
def test_aes_ccm_iv(device, size, iv_len):
|
||||||
|
pkey, keyid = generate_key(device, size)
|
||||||
|
iv = os.urandom(iv_len)
|
||||||
|
ctA = device.aes(keyid, EncryptionMode.ENCRYPT, AES.CCM, MESSAGE, iv=iv, aad=AAD)
|
||||||
|
|
||||||
|
encryptor = aead.AESCCM(pkey)
|
||||||
|
ctB = encryptor.encrypt(iv, MESSAGE, AAD)
|
||||||
|
assert(ctA == ctB)
|
||||||
|
|
||||||
|
dtA = device.aes(keyid, EncryptionMode.DECRYPT, AES.CCM, ctA, iv=iv, aad=AAD)
|
||||||
|
decryptor = encryptor
|
||||||
|
dtB = decryptor.decrypt(iv, ctB, AAD)
|
||||||
|
assert(dtA == dtB)
|
||||||
|
assert(dtA == MESSAGE)
|
||||||
|
device.delete_key(keyid)
|
||||||
|
|||||||
Reference in New Issue
Block a user