Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add AES in counter mode support #119

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions PyKCS11/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,29 @@ def to_native(self):
return self._mech


class AES_CTR_Mechanism(object):
"""CKM_AES_CTR encryption mechanism"""

def __init__(self, counterBits, counterBlock):
"""
:param counterBits: the number of incremented bits in the counter block
:param counterBlock: a 16-byte initial value of the counter block
"""
self._param = PyKCS11.LowLevel.CK_AES_CTR_PARAMS()

self._source_cb = ckbytelist(counterBlock)
self._param.ulCounterBits = counterBits
self._param.cb = self._source_cb

self._mech = PyKCS11.LowLevel.CK_MECHANISM()
self._mech.mechanism = CKM_AES_CTR
self._mech.pParameter = self._param
self._mech.ulParameterLen = PyKCS11.LowLevel.CK_AES_CTR_PARAMS_LENGTH

def to_native(self):
return self._mech


class RSAOAEPMechanism(object):
"""RSA OAEP Wrapping mechanism"""

Expand Down
8 changes: 8 additions & 0 deletions src/opensc/pkcs11.h
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,11 @@ struct ck_gcm_params {
unsigned long ulTagBits;
} ;

struct ck_aes_ctr_params {
unsigned long ulCounterBits;
unsigned char cb[16];
} ;

struct ck_ecdh1_derive_params {
unsigned long kdf;
unsigned long ulSharedDataLen;
Expand Down Expand Up @@ -1335,6 +1340,9 @@ typedef struct ck_rsa_pkcs_pss_params *CK_RSA_PKCS_PSS_PARAMS_PTR;

typedef struct ck_gcm_params CK_GCM_PARAMS;

typedef struct ck_aes_ctr_params CK_AES_CTR_PARAMS;
typedef struct ck_aes_ctr_params *CK_AES_CTR_PARAMS_PTR;

typedef struct ck_ecdh1_derive_params CK_ECDH1_DERIVE_PARAMS;
typedef struct ck_ecdh1_derive_params *CK_ECDH1_DERIVE_PARAMS_PTR;

Expand Down
82 changes: 69 additions & 13 deletions src/pykcs11.i
Original file line number Diff line number Diff line change
Expand Up @@ -245,23 +245,61 @@ typedef struct CK_DATE{
}
else
{
// If the value being set is of CK_RSA_PKCS_OAEP_PARAMS type:
int res2 = SWIG_ConvertPtr($input, &arg2, $descriptor(CK_RSA_PKCS_OAEP_PARAMS*), 0);
if (!SWIG_IsOK(res2)) {
res2 = SWIG_ConvertPtr($input, &arg2, $descriptor(CK_RSA_PKCS_PSS_PARAMS*), 0);
if (!SWIG_IsOK(res2)) {
// If the value isn't a ckbytelist, then it must be a pointer to a mechanism parameter
int res2 = -1;
do { // Add mechanism parameters here
res2 = SWIG_ConvertPtr($input, &arg2, $descriptor(CK_RSA_PKCS_OAEP_PARAMS*), 0);
if( SWIG_IsOK( res2 ) )
break;

res2 = SWIG_ConvertPtr($input, &arg2, $descriptor(CK_RSA_PKCS_PSS_PARAMS*), 0);
if( SWIG_IsOK( res2 ) )
break;

res2 = SWIG_ConvertPtr($input, &arg2, $descriptor(CK_GCM_PARAMS*), 0);
if (!SWIG_IsOK(res2)) {
res2 = SWIG_ConvertPtr($input, &arg2, $descriptor(CK_ECDH1_DERIVE_PARAMS*), 0);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "unsupported CK_MECHANISM Parameter type.");
}
}
}
}
if( SWIG_IsOK( res2 ) )
break;

res2 = SWIG_ConvertPtr($input, &arg2, $descriptor(CK_ECDH1_DERIVE_PARAMS*), 0);
if( SWIG_IsOK( res2 ) )
break;

res2 = SWIG_ConvertPtr($input, &arg2, $descriptor(CK_AES_CTR_PARAMS*), 0);
if( SWIG_IsOK( res2 ) )
break;
} while(0);

if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "unsupported CK_MECHANISM Parameter type.");
}
}
}

// typemap for CK_BYTE static arrays
%typemap(in) unsigned char[ANY](unsigned char out[$1_dim0]) {
vector<unsigned char> *vect;
// Expect a value of ckbytelist type:
int res = SWIG_ConvertPtr($input, (void **)&vect, $descriptor(vector<unsigned char> *), 0);
if (SWIG_IsOK(res))
{
if (vect->size() != $1_dim0)
{
SWIG_exception_fail(SWIG_ValueError, "Expected a ckbytelist with $1_dim0 elements");
}

for (size_t i = 0; i < $1_dim0; i++)
{
out[i] = (*vect)[i];
}
}
else
{
// If a mechanism parameter has a CK_BYTE array as a member, it must be represented as a ckbytelist
SWIG_exception_fail(SWIG_ArgError(res), "CK_BYTE arrays of CK_* mechanism params must be represented as ckbytelist type");
}
$1 = &out[0];
}

typedef struct CK_MECHANISM {
unsigned long mechanism;
void* pParameter;
Expand Down Expand Up @@ -318,6 +356,24 @@ typedef struct CK_GCM_PARAMS {

%constant int CK_GCM_PARAMS_LENGTH = sizeof(CK_GCM_PARAMS);

typedef struct CK_AES_CTR_PARAMS {
unsigned long ulCounterBits;
unsigned char cb[16];
} CK_AES_CTR_PARAMS;

%extend CK_AES_CTR_PARAMS
{
CK_AES_CTR_PARAMS()
{
CK_AES_CTR_PARAMS *p = new CK_AES_CTR_PARAMS();
p->ulCounterBits = 128;
memset(p->cb, 0, sizeof(p->cb));
return p;
}
};

%constant int CK_AES_CTR_PARAMS_LENGTH = sizeof(CK_AES_CTR_PARAMS);

typedef struct CK_RSA_PKCS_OAEP_PARAMS {
unsigned long hashAlg;
unsigned long mgf;
Expand Down
11 changes: 11 additions & 0 deletions test/test_symetric.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,17 @@ def test_symetric(self):
# 2nd block
self.assertSequenceEqual(DataOut[16:], DataECBOut2)

# AES CTR with IV
mechanism = PyKCS11.AES_CTR_Mechanism(128, "1234567812345678")

DataOut = self.session.encrypt(symKey, DataIn, mechanism)
# print("DataOut", DataOut)

DataCheck = self.session.decrypt(symKey, DataOut, mechanism)
# print("DataCheck:", DataCheck)

self.assertSequenceEqual(DataIn, DataCheck)

#
# test CK_GCM_PARAMS
#
Expand Down
Loading