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

WiP: add support for ECDH key derivation #91

Closed
wants to merge 1 commit into from
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
56 changes: 56 additions & 0 deletions PyKCS11/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

CKA = {}
CKC = {}
CKD = {}
CKF = {}
CKG = {}
CKH = {}
Expand All @@ -46,6 +47,7 @@
for x in PyKCS11.LowLevel.__dict__.keys():
if x[:4] == 'CKA_' \
or x[:4] == 'CKC_' \
or x[:4] == 'CKD_' \
or x[:4] == 'CKF_' \
or x[:4] == 'CKG_' \
or x[:4] == 'CKH_' \
Expand Down Expand Up @@ -827,6 +829,38 @@ def __init__(self, mecha, hashAlg, mgf, sLen):
def to_native(self):
return self._mech

class ECDH1_DERIVE_Mechanism(object):
"""CKM_ECDH1_DERIVE key derivation mechanism"""

def __init__(self, kdf, sharedData, publicData):
"""
:param kdf: Key derivation function
:param sharedData: additional shared data
:param publicData: Other party public key (encoded uncompressed or concatenated x and y coordinates)
"""
self._param = PyKCS11.LowLevel.CK_ECDH1_DERIVE_PARAMS()

self._param.kdf = kdf

if sharedData:
self._shared_data = ckbytelist(sharedData)
self._param.pSharedData = self._shared_data
self._param.ulSharedDataLen = len(self._shared_data)
else:
self._source_shared_data = None

self._public_data = ckbytelist(publicData)
self._param.pPublicData = self._public_data
self._param.ulPublicDataLen = len(self._public_data)

self._mech = PyKCS11.LowLevel.CK_MECHANISM()
self._mech.mechanism = CKM_ECDH1_DERIVE
self._mech.pParameter = self._param
self._mech.ulParameterLen = PyKCS11.LowLevel.CK_ECDH1_DERIVE_PARAMS_LENGTH

def to_native(self):
return self._mech


class DigestSession(object):
def __init__(self, lib, session, mecha):
Expand Down Expand Up @@ -1255,6 +1289,28 @@ def unwrapKey(self, unwrappingKey, wrappedKey, template,
raise PyKCS11Error(rv)
return handle

def deriveKey(self, baseKey, template, mecha):
"""
C_DeriveKey

:param baseKey: the base key handle
:type baseKey: integer
:param template: template for the unwrapped key
:param mecha: the decrypt mechanism to be used (use
`ECDH1_DERIVE_Mechanism(...)` for `CKM_ECDH1_DERIVE`)
:type mecha: :class:`Mechanism`
:return: the unwrapped key object
:rtype: integer

"""
m = mecha.to_native()
handle = PyKCS11.LowLevel.CK_OBJECT_HANDLE()
attrs = self._template2ckattrlist(template)
rv = self.lib.C_DeriveKey(self.session, m, baseKey, attrs, handle)
if rv != CKR_OK:
raise PyKCS11Error(rv)
return handle

def isNum(self, type):
"""
is the type a numerical value?
Expand Down
16 changes: 16 additions & 0 deletions src/opensc/pkcs11.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ extern "C" {
#define source_data pSourceData
#define source_data_len ulSourceDataLen

#define ck_ecdh1_derive_params CK_ECDH1_DERIVE_PARAMS

#define ck_rv_t CK_RV
#define ck_notify_t CK_NOTIFY

Expand Down Expand Up @@ -682,6 +684,11 @@ typedef unsigned long ck_mechanism_type_t;
#define CKG_MGF1_SHA384 (0x00000003)
#define CKG_MGF1_SHA512 (0x00000004)

#define CKD_NULL (0x00000001)
#define CKD_SHA1_KDF (0x00000002)
#define CKD_SHA1_KDF_ASN1 (0x00000003)
#define CKD_SHA1_KDF_CONCATENATE (0x00000004)


struct ck_mechanism
{
Expand Down Expand Up @@ -722,6 +729,15 @@ struct ck_gcm_params {
unsigned long ulTagBits;
} ;

struct ck_ecdh1_derive_params {
unsigned long kdf;
unsigned long ulSharedDataLen;
void * pSharedData;
unsigned long ulPublicDataLen;
void * pPublicData;
} ;


#define CKF_HW (1 << 0)
#define CKF_ENCRYPT (1 << 8)
#define CKF_DECRYPT (1 << 9)
Expand Down
28 changes: 28 additions & 0 deletions src/pkcs11lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,34 @@ CK_RV CPKCS11Lib::C_UnwrapKey(
return rv;
}


CK_RV CPKCS11Lib::C_DeriveKey(
CK_SESSION_HANDLE hSession,
CK_MECHANISM *pMechanism,
CK_OBJECT_HANDLE hBaseKey,
vector<CK_ATTRIBUTE_SMART> Template,
CK_OBJECT_HANDLE & outKey)
{
CPKCS11LIB_PROLOGUE(C_DeriveKey);
CK_OBJECT_HANDLE hKey = static_cast<CK_OBJECT_HANDLE>(outKey);

CK_ULONG ulAttributeCount = 0;
CK_ATTRIBUTE* pTemplate = AttrVector2Template(Template, ulAttributeCount);

rv = m_pFunc->C_DeriveKey(hSession,
pMechanism,
hBaseKey,
pTemplate,
ulAttributeCount,
&hKey);

if (pTemplate)
DestroyTemplate(pTemplate, ulAttributeCount);
outKey = static_cast<CK_OBJECT_HANDLE>(hKey);
CPKCS11LIB_EPILOGUE;
return rv;
}

CK_RV CPKCS11Lib::C_SeedRandom(
CK_SESSION_HANDLE hSession,
vector<unsigned char> Seed)
Expand Down
7 changes: 7 additions & 0 deletions src/pkcs11lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,13 @@ class CPKCS11Lib
vector<CK_ATTRIBUTE_SMART> Template,
CK_OBJECT_HANDLE & outhKey);

CK_RV C_DeriveKey(
CK_SESSION_HANDLE hSession,
CK_MECHANISM *pMechanism,
CK_OBJECT_HANDLE hBaseKey,
vector<CK_ATTRIBUTE_SMART> Template,
CK_OBJECT_HANDLE & outkey);

CK_RV C_SeedRandom(
CK_SESSION_HANDLE hSession,
vector<unsigned char> Seed);
Expand Down
38 changes: 35 additions & 3 deletions src/pykcs11.i
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,10 @@ typedef struct CK_DATE{
if (!SWIG_IsOK(res2)) {
res2 = SWIG_ConvertPtr($input, &arg2, $descriptor(CK_GCM_PARAMS*), 0);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "unsupported CK_MECHANISM Parameter type.");
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.");
}
}
}
}
Expand Down Expand Up @@ -295,8 +298,8 @@ typedef struct CK_GCM_PARAMS {

%constant int CK_GCM_PARAMS_LENGTH = sizeof(CK_GCM_PARAMS);

%typemap(in) void*;
%typemap(in) void* = char*;
//%typemap(in) void*;
//%typemap(in) void* = char*;

typedef struct CK_RSA_PKCS_OAEP_PARAMS {
unsigned long hashAlg;
Expand Down Expand Up @@ -345,6 +348,35 @@ typedef struct CK_RSA_PKCS_PSS_PARAMS {

%constant int CK_RSA_PKCS_PSS_PARAMS_LENGTH = sizeof(CK_RSA_PKCS_PSS_PARAMS);

//%typemap(in) void*;
//%typemap(in) void* = char*;

typedef struct CK_ECDH1_DERIVE_PARAMS {
unsigned long kdf;
unsigned long ulSharedDataLen;
void* pSharedData;
unsigned long ulPublicDataLen;
void* pPublicData;
} CK_ECDH1_DERIVE_PARAMS;

%extend CK_ECDH1_DERIVE_PARAMS
{
CK_ECDH1_DERIVE_PARAMS()
{
CK_ECDH1_DERIVE_PARAMS *p = new CK_ECDH1_DERIVE_PARAMS();
p->kdf = CKD_NULL;
p->pSharedData = NULL;
p->ulSharedDataLen = 0;
p->pPublicData = NULL;
p->ulPublicDataLen = 0;

return p;
}
};

%constant int CK_ECDH1_DERIVE_PARAMS_LENGTH = sizeof(CK_ECDH1_DERIVE_PARAMS);


typedef struct CK_MECHANISM_INFO {
%immutable;
unsigned long ulMinKeySize;
Expand Down