/* No padding or other stuff needed. We can call PKCS11 from here */ static int pkcs11_ecdsa_sign(const unsigned char *msg, unsigned int msg_len, unsigned char *sigret, unsigned int *siglen, PKCS11_KEY *key) { int rv; PKCS11_SLOT *slot = KEY2SLOT(key); PKCS11_CTX *ctx = KEY2CTX(key); PKCS11_KEY_private *kpriv = PRIVKEY(key); PKCS11_SLOT_private *spriv = PRIVSLOT(slot); CK_MECHANISM mechanism; CK_ULONG ck_sigsize; ck_sigsize = *siglen; memset(&mechanism, 0, sizeof(mechanism)); mechanism.mechanism = CKM_ECDSA; CRYPTO_THREAD_write_lock(PRIVSLOT(slot)->rwlock); rv = CRYPTOKI_call(ctx, C_SignInit(spriv->session, &mechanism, kpriv->object)); if (!rv) rv = pkcs11_authenticate(key); if (!rv) rv = CRYPTOKI_call(ctx, C_Sign(spriv->session, (CK_BYTE *)msg, msg_len, sigret, &ck_sigsize)); CRYPTO_THREAD_unlock(PRIVSLOT(slot)->rwlock); if (rv) { PKCS11err(PKCS11_F_PKCS11_EC_KEY_SIGN, pkcs11_map_err(rv)); return -1; } *siglen = ck_sigsize; return ck_sigsize; }
void CPKCSDemoDlg::OnBtnSign() { StartOP(); CK_RV rv; rv = C_SignInit(m_hSession, &ckMechanism, m_hPriKey); if(CKR_OK != rv) { ShowErr(NEWLINE"Failed to call SignInit!Error code 0x%08X."NEWLINE, rv); return; } rv = C_Sign(m_hSession, pbMsg, ulMsgLen, m_pSignature, &m_ulSignatureLen); if(CKR_OK != rv) { ShowErr(NEWLINE"Failed to Sign!Error code 0x%08X."NEWLINE, rv); return; } else { ShowMsg(NEWLINE"Data:"NEWLINE); ShowMsg((char*)pbMsg); ShowMsg(NEWLINE" was Signed successfully!"NEWLINE"Signed Data is:"NEWLINE); ShowMsg(nByteToStr(m_ulSignatureLen, m_pSignature, 1, 16)); ShowMsg(NEWLINE""NEWLINE"Now you can do RSA Verification!"NEWLINE); m_btnVerify.EnableWindow(TRUE); } }
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiSign::SignInternal___SZARRAY_U1__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack ) { TINYCLR_HEADER(); CLR_RT_HeapBlock* pThis = stack.This(); CLR_RT_HeapBlock_Array* pData = stack.Arg1().DereferenceArray(); CLR_RT_HeapBlock_Array* pRes; CLR_INT32 offset = stack.Arg2().NumericByRef().s4; CLR_INT32 len = stack.Arg3().NumericByRef().s4; CLR_RT_HeapBlock* pSession = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference(); CK_SESSION_HANDLE hSession; CK_ULONG sigLen = 0; CLR_RT_HeapBlock hbRef; FAULT_ON_NULL(pSession); FAULT_ON_NULL_ARG(pData); if((offset + len) > (CLR_INT32)pData->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); hSession = (CK_SESSION_HANDLE)pSession[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Session::FIELD__m_handle].NumericByRef().s4; if(hSession == CK_SESSION_HANDLE_INVALID) TINYCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); CRYPTOKI_CHECK_RESULT(stack, C_Sign(hSession, pData->GetElement(offset), len, NULL, (CK_ULONG_PTR)&sigLen)); TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(hbRef, sigLen, g_CLR_RT_WellKnownTypes.m_UInt8)); pRes = hbRef.DereferenceArray(); CRYPTOKI_CHECK_RESULT(stack, C_Sign(hSession, pData->GetElement(offset), len, pRes->GetFirstElement(), (CK_ULONG_PTR)&sigLen)); if(sigLen < pRes->m_numOfElements) { TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(stack.PushValue(), sigLen, g_CLR_RT_WellKnownTypes.m_UInt8)); memcpy(stack.TopValue().DereferenceArray()->GetFirstElement(), pRes->GetFirstElement(), sigLen); } else { stack.SetResult_Object(pRes); } TINYCLR_NOCLEANUP(); }
/* OpenSSL assumes that the output buffer is always big enough */ int pkcs11_private_encrypt(int flen, const unsigned char *from, unsigned char *to, PKCS11_KEY *key, int padding) { PKCS11_SLOT *slot = KEY2SLOT(key); PKCS11_CTX *ctx = KEY2CTX(key); PKCS11_KEY_private *kpriv = PRIVKEY(key); PKCS11_SLOT_private *spriv = PRIVSLOT(slot); CK_MECHANISM mechanism; CK_ULONG size; int rv; size = pkcs11_get_key_size(key); if (pkcs11_mechanism(&mechanism, padding) < 0) return -1; CRYPTO_THREAD_write_lock(PRIVSLOT(slot)->rwlock); /* Try signing first, as applications are more likely to use it */ rv = CRYPTOKI_call(ctx, C_SignInit(spriv->session, &mechanism, kpriv->object)); if (rv == CKR_USER_NOT_LOGGED_IN) rv = pkcs11_authenticate(key); if (!rv) rv = CRYPTOKI_call(ctx, C_Sign(spriv->session, (CK_BYTE *)from, flen, to, &size)); if (rv == CKR_KEY_FUNCTION_NOT_PERMITTED) { /* OpenSSL may use it for encryption rather than signing */ rv = CRYPTOKI_call(ctx, C_EncryptInit(spriv->session, &mechanism, kpriv->object)); if (rv == CKR_USER_NOT_LOGGED_IN) rv = pkcs11_authenticate(key); if (!rv) rv = CRYPTOKI_call(ctx, C_Encrypt(spriv->session, (CK_BYTE *)from, flen, to, &size)); } CRYPTO_THREAD_unlock(PRIVSLOT(slot)->rwlock); if (rv) { PKCS11err(PKCS11_F_PKCS11_RSA_ENCRYPT, pkcs11_map_err(rv)); return -1; } return size; }
int PKCS11_ecdsa_sign(const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, PKCS11_KEY * key) { /* signature size is the issue, will assume caller has a big buffer ! */ /* No padding or other stuff needed, we can cal PKCS11 from here */ int rv; PKCS11_KEY_private *priv; PKCS11_SLOT *slot; PKCS11_CTX *ctx; CK_SESSION_HANDLE session; CK_MECHANISM mechanism; CK_ULONG ck_sigsize; ctx = KEY2CTX(key); priv = PRIVKEY(key); slot = TOKEN2SLOT(priv->parent); CHECK_KEY_FORK(key); session = PRIVSLOT(slot)->session; ck_sigsize = *siglen; memset(&mechanism, 0, sizeof(mechanism)); mechanism.mechanism = CKM_ECDSA; pkcs11_w_lock(PRIVSLOT(slot)->lockid); rv = CRYPTOKI_call(ctx, C_SignInit(session, &mechanism, priv->object)) || CRYPTOKI_call(ctx, C_Sign(session, (CK_BYTE *) m, m_len, sigret, &ck_sigsize)); pkcs11_w_unlock(PRIVSLOT(slot)->lockid); if (rv) { PKCS11err(PKCS11_F_PKCS11_EC_KEY_SIGN, pkcs11_map_err(rv)); return -1; } *siglen = ck_sigsize; return ck_sigsize; }
int PKCS11_private_encrypt(int flen, const unsigned char *from, unsigned char *to, PKCS11_KEY * key, int padding) { PKCS11_KEY_private *priv; PKCS11_SLOT *slot; PKCS11_CTX *ctx; CK_SESSION_HANDLE session; CK_MECHANISM mechanism; int rv; int sigsize; CK_ULONG ck_sigsize; if (key == NULL) return -1; sigsize=PKCS11_get_key_size(key); ck_sigsize=sigsize; memset(&mechanism, 0, sizeof(mechanism)); switch (padding) { case RSA_NO_PADDING: mechanism.mechanism = CKM_RSA_X_509; break; case RSA_PKCS1_PADDING: if ((flen + RSA_PKCS1_PADDING_SIZE) > sigsize) { return -1; /* the size is wrong */ } mechanism.mechanism = CKM_RSA_PKCS; break; default: printf("pkcs11 engine: only RSA_NO_PADDING or RSA_PKCS1_PADDING allowed so far\n"); return -1; } ctx = KEY2CTX(key); priv = PRIVKEY(key); slot = TOKEN2SLOT(priv->parent); CHECK_KEY_FORK(key); session = PRIVSLOT(slot)->session; pkcs11_w_lock(PRIVSLOT(slot)->lockid); /* API is somewhat fishy here. *siglen is 0 on entry (cleared * by OpenSSL). The library assumes that the memory passed * by the caller is always big enough */ rv = CRYPTOKI_call(ctx, C_SignInit(session, &mechanism, priv->object)) || CRYPTOKI_call(ctx, C_Sign(session, (CK_BYTE *) from, flen, to, &ck_sigsize)); pkcs11_w_unlock(PRIVSLOT(slot)->lockid); if (rv) { PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv)); return -1; } if ((unsigned)sigsize != ck_sigsize) return -1; return sigsize; }