pkcs11c.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,203 行 · 第 1/5 页
C
2,203 行
pk11_FreeContext(context); pk11_SetContextByType(session, PK11_ENCRYPT, NULL); pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;}/* ************** Crypto Functions: Decrypt ************************ *//* NSC_DecryptInit initializes a decryption operation. */static CK_RV pk11_DecryptInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE dtype, PK11ContextType contextType){ PK11Session *session; PK11Object *key; PK11Attribute *att; PK11SessionContext *context; CK_RC2_CBC_PARAMS *rc2_param;#if NSS_SOFTOKEN_DOES_RC5 CK_RC5_CBC_PARAMS *rc5_param; SECItem rc5Key;#endif CK_KEY_TYPE key_type; CK_RV crv = CKR_OK; unsigned effectiveKeyLength; SECKEYLowPrivateKey *privKey; unsigned char newdeskey[8]; PRBool useNewKey=PR_FALSE; int t; session = pk11_SessionFromHandle(hSession); if (session == NULL) return CKR_SESSION_HANDLE_INVALID; crv = pk11_InitGeneric(session,&context,contextType,&key,hKey,&key_type, CKO_PRIVATE_KEY,dtype); if (crv != CKR_OK) { pk11_FreeSession(session); return crv; } /* * now handle each mechanism */ switch(pMechanism->mechanism) { case CKM_RSA_PKCS: case CKM_RSA_X_509: if (key_type != CKK_RSA) { crv = CKR_KEY_TYPE_INCONSISTENT; break; } context->multi = PR_FALSE; privKey = pk11_GetPrivKey(key,CKK_RSA); if (privKey == NULL) { crv = CKR_HOST_MEMORY; break; } context->cipherInfo = privKey; context->update = (PK11Cipher) (pMechanism->mechanism == CKM_RSA_X_509 ? RSA_DecryptRaw : RSA_DecryptBlock); context->destroy = (context->cipherInfo == key->objectInfo) ? (PK11Destroy) pk11_Null : (PK11Destroy) pk11_FreePrivKey; break; case CKM_RC2_CBC_PAD: context->doPad = PR_TRUE; context->blockSize = 8; /* fall thru */ case CKM_RC2_ECB: case CKM_RC2_CBC: if (key_type != CKK_RC2) { crv = CKR_KEY_TYPE_INCONSISTENT; break; } att = pk11_FindAttribute(key,CKA_VALUE); rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter; effectiveKeyLength = (rc2_param->ulEffectiveBits+7)/8; context->cipherInfo = RC2_CreateContext((unsigned char*)att->attrib.pValue, att->attrib.ulValueLen, rc2_param->iv, pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 : NSS_RC2_CBC, effectiveKeyLength); pk11_FreeAttribute(att); if (context->cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } context->update = (PK11Cipher) RC2_Decrypt; context->destroy = (PK11Destroy) RC2_DestroyContext; break;#if NSS_SOFTOKEN_DOES_RC5 case CKM_RC5_CBC_PAD: context->doPad = PR_TRUE; /* fall thru */ case CKM_RC5_ECB: case CKM_RC5_CBC: if (key_type != CKK_RC5) { crv = CKR_KEY_TYPE_INCONSISTENT; break; } att = pk11_FindAttribute(key,CKA_VALUE); if (att == NULL) { crv = CKR_KEY_HANDLE_INVALID; break; } rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter; if (context->doPad) { context->blockSize = rc5_param->ulWordsize*2; } rc5Key.data = (unsigned char*)att->attrib.pValue; rc5Key.len = att->attrib.ulValueLen; context->cipherInfo = RC5_CreateContext(&rc5Key,rc5_param->ulRounds, rc5_param->ulWordsize,rc5_param->pIv, pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC); pk11_FreeAttribute(att); if (context->cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } context->update = (PK11Cipher) RC5_Decrypt; context->destroy = (PK11Destroy) RC5_DestroyContext; break;#endif case CKM_RC4: if (key_type != CKK_RC4) { crv = CKR_KEY_TYPE_INCONSISTENT; break; } att = pk11_FindAttribute(key,CKA_VALUE); context->cipherInfo = RC4_CreateContext((unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); pk11_FreeAttribute(att); if (context->cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } context->update = (PK11Cipher) RC4_Decrypt; context->destroy = (PK11Destroy) RC4_DestroyContext; break; case CKM_CDMF_CBC_PAD: context->doPad = PR_TRUE; context->blockSize = 8; /* fall thru */ case CKM_CDMF_ECB: case CKM_CDMF_CBC: if (key_type != CKK_CDMF) { crv = CKR_KEY_TYPE_INCONSISTENT; break; } t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC; useNewKey = PR_TRUE; if (crv != CKR_OK) break; goto finish_des; case CKM_DES_ECB: if (key_type != CKK_DES) { crv = CKR_KEY_TYPE_INCONSISTENT; break; } t = NSS_DES; goto finish_des; case CKM_DES_CBC_PAD: context->doPad = PR_TRUE; context->blockSize = 8; /* fall thru */ case CKM_DES_CBC: if (key_type != CKK_DES) { crv = CKR_KEY_TYPE_INCONSISTENT; break; } t = NSS_DES_CBC; goto finish_des; case CKM_DES3_ECB: if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) { crv = CKR_KEY_TYPE_INCONSISTENT; break; } t = NSS_DES_EDE3; goto finish_des; case CKM_DES3_CBC_PAD: context->doPad = PR_TRUE; context->blockSize = 8; /* fall thru */ case CKM_DES3_CBC: if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) { crv = CKR_KEY_TYPE_INCONSISTENT; break; } t = NSS_DES_EDE3_CBC;finish_des: att = pk11_FindAttribute(key,CKA_VALUE); if (att == NULL) { crv = CKR_KEY_HANDLE_INVALID; break; } if (useNewKey) { crv = pk11_cdmf2des((unsigned char*)att->attrib.pValue,newdeskey); if (crv != CKR_OK) { pk11_FreeAttribute(att); break; } } context->cipherInfo = DES_CreateContext( useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue, (unsigned char*)pMechanism->pParameter,t, PR_FALSE); pk11_FreeAttribute(att); if (context->cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } context->update = (PK11Cipher) DES_Decrypt; context->destroy = (PK11Destroy) DES_DestroyContext; break; default: crv = CKR_MECHANISM_INVALID; break; } pk11_FreeObject(key); if (crv != CKR_OK) { pk11_FreeContext(context); pk11_FreeSession(session); return crv; } pk11_SetContextByType(session, contextType, context); pk11_FreeSession(session); return CKR_OK;}/* NSC_DecryptInit initializes a decryption operation. */CK_RV NSC_DecryptInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey){ return pk11_DecryptInit(hSession,pMechanism,hKey,CKA_DECRYPT,PK11_DECRYPT);}/* NSC_DecryptUpdate continues a multiple-part decryption operation. */CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen){ PK11SessionContext *context; unsigned int padoutlen = 0; unsigned int outlen; unsigned int maxout = *pulPartLen; CK_RV crv; SECStatus rv; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_TRUE,NULL); if (crv != CKR_OK) return crv; if (context->doPad) { /* first decrypt our saved buffer */ if (context->padDataLength != 0) { rv = (*context->update)(context->cipherInfo, pPart, &padoutlen, maxout, context->padBuf, context->blockSize); if (rv != SECSuccess) return CKR_DEVICE_ERROR; pPart += padoutlen; maxout -= padoutlen; } /* now save the final block for the next decrypt or the final */ PORT_Memcpy(context->padBuf,&pEncryptedPart[ulEncryptedPartLen - context->blockSize], context->blockSize); context->padDataLength = context->blockSize; ulEncryptedPartLen -= context->padDataLength; } /* do it: NOTE: this assumes buf size in is >= buf size out! */ rv = (*context->update)(context->cipherInfo,pPart, &outlen, maxout, pEncryptedPart, ulEncryptedPartLen); *pulPartLen = (CK_ULONG) (outlen + padoutlen); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;}/* NSC_DecryptFinal finishes a multiple-part decryption operation. */CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen){ PK11Session *session; PK11SessionContext *context; unsigned int outlen; unsigned int maxout = *pulLastPartLen; CK_RV crv; SECStatus rv = SECSuccess; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_TRUE,&session); if (crv != CKR_OK) return crv; *pulLastPartLen = 0; if (context->doPad) { /* decrypt our saved buffer */ if (context->padDataLength != 0) { /* this assumes that pLastPart is big enough to hold the *whole* * buffer!!! */ rv = (*context->update)(context->cipherInfo, pLastPart, &outlen, maxout, context->padBuf, context->blockSize); if (rv == SECSuccess) { unsigned int padSize = (unsigned int) pLastPart[context->blockSize-1]; *pulLastPartLen = outlen - padSize; } } } /* do it */ pk11_SetContextByType(session, PK11_DECRYPT, NULL); pk11_FreeContext(context); pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;}/* NSC_Decrypt decrypts encrypted data in a single part. */CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen){ PK11Session *session; PK11SessionContext *context; unsigned int outlen; unsigned int maxoutlen = *pulDataLen; CK_RV crv; CK_RV crv2; SECStatus rv; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_FALSE,&session); if (crv != CKR_OK) return crv; if (context->doPad) { CK_ULONG finalLen; /* padding is fairly complicated, have the update and final * code deal with it */ pk11_FreeSession(session); crv = NSC_DecryptUpdate(hSession,pEncryptedData,ulEncryptedDataLen, pData, pulDataLen); if (crv != CKR_OK) *pulDataLen = 0; maxoutlen -= *pulDataLen; pData += *pulDataLen; finalLen = maxoutlen; crv2 = NSC_DecryptFinal(hSession, pData, &finalLen); if (crv2 == CKR_OK) { *pulDataLen += finalLen; } return crv == CKR_OK ? crv2 :crv; } rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, pEncryptedData, ulEncryptedDataLen); *pulDataLen = (CK_ULONG) outlen; pk11_FreeContext(context); pk11_SetContextByType(session, PK11_DECRYPT, NULL); pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;}/* ************** Crypto Functions: Digest (HASH) ************************ *//* NSC_DigestInit initializes a message-digesting operation. */CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism){ PK11Session *session; PK11SessionContext *context; MD2Context *md2_context; MD5Context *md5_context; SHA1Context *sha1_context; CK_RV crv = CKR_OK; session = pk11_SessionFromHandle(hSession); if (session == NULL) return CKR_SESSION_HANDLE_INVALID; crv = pk11_InitGeneric(session,&context,PK11_HASH,NULL,0,NULL, 0, 0); if (crv != CKR_OK) { pk11_FreeSession(session); return crv; } switch(pMechanism->mechanism) { case CKM_MD2: md2_context = MD2_NewContext(); context->cipherInfo = (void *)md2_context; context->cipherInfoLen = MD2_FlattenSize(md2_context); context->currentMech = CKM_MD2; if (context->cipherInfo == NULL) { crv= CKR_HOST_MEMORY; } context->hashUpdate = (PK11Hash) MD2_Update; context->end = (PK11End) MD2_End; context->destroy = (PK11Destroy) MD2_DestroyContext; MD2_Begin(md2_context); break; case CKM_MD5: md5_context = MD5_NewContext(); context->cipherInfo = (void *)md5_context; context->cipherInfoLen = MD5_FlattenSize(md5_context); context->currentMech = CKM_MD5; if (context->cipherInfo == NULL) { crv= CKR_HOST_MEMORY; } context->hashUpdate = (PK11Hash) MD5_Update; context->end = (PK11End) MD5_End; context->destroy = (PK11Destroy) MD5_DestroyContext; MD5_Begin(md5_context); break; case CKM_SHA_1: sha1_context = SHA1_NewContext(); context->cipherInfo = (void *)sha1_context; context->cipherInfoLen = SHA1_FlattenSize(sha1_context); context->currentMech = CKM_SHA_1; if (context->cipherInfo == NULL) { crv= CKR_HOST_MEMORY; break; } context->hashUpdate = (PK11Hash) SHA1_Update; context->end = (PK11End) SHA1_End; context->destroy = (PK11Destroy) SHA1_DestroyContext; SHA1_Begin(sha1_context); break; default: crv = CKR_MECHANISM_INVALID; break; } if (crv != CKR_OK) { pk11_FreeContext(context); pk11_FreeSession(session); return crv; } pk11_SetContextByType(session, PK11_HASH, context); pk11_FreeSession(session); return CKR_OK;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?