pkcs11c.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,203 行 · 第 1/5 页
C
2,203 行
return CKR_OK;}/* ************** Crypto Functions: Encrypt ************************ *//* * All the NSC_InitXXX functions have a set of common checks and processing they * all need to do at the beginning. This is done here. */static CK_RVpk11_InitGeneric(PK11Session *session,PK11SessionContext **contextPtr, PK11ContextType ctype,PK11Object **keyPtr, CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr, CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation){ PK11Object *key = NULL; PK11Attribute *att; PK11SessionContext *context; /* We can only init if there is not current context active */ if (pk11_ReturnContextByType(session,ctype) != NULL) { return CKR_OPERATION_ACTIVE; } /* find the key */ if (keyPtr) { key = pk11_ObjectFromHandle(hKey,session); if (key == NULL) { return CKR_KEY_HANDLE_INVALID; } /* make sure it's a valid key for this operation */ if (((key->objclass != CKO_SECRET_KEY) && (key->objclass != pubKeyType)) || !pk11_isTrue(key,operation)) { pk11_FreeObject(key); return CKR_KEY_TYPE_INCONSISTENT; } /* get the key type */ att = pk11_FindAttribute(key,CKA_KEY_TYPE); PORT_Assert(att != NULL); *keyTypePtr = *(CK_KEY_TYPE *)att->attrib.pValue; pk11_FreeAttribute(att); *keyPtr = key; } /* allocate the context structure */ context = (PK11SessionContext *)PORT_Alloc(sizeof(PK11SessionContext)); if (context == NULL) { if (key) pk11_FreeObject(key); return CKR_HOST_MEMORY; } context->type = ctype; context->multi = PR_TRUE; context->cipherInfo = NULL; context->hashInfo = NULL; context->doPad = PR_FALSE; context->padDataLength = 0; *contextPtr = context; return CKR_OK;}/* NSC_EncryptInit initializes an encryption operation. *//* This function is used by NSC_EncryptInit and NSC_WrapKey. The only difference * in their uses if whether or not etype is CKA_ENCRYPT or CKA_WRAP */static CK_RVpk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype, PK11ContextType contextType){ PK11Session *session; PK11Object *key; PK11SessionContext *context; PK11Attribute *att; 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; SECKEYLowPublicKey *pubKey; unsigned effectiveKeyLength; 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_PUBLIC_KEY, etype); if (crv != CKR_OK) { pk11_FreeSession(session); return crv; } context->doPad = PR_FALSE; 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; pubKey = pk11_GetPubKey(key,CKK_RSA); if (pubKey == NULL) { crv = CKR_HOST_MEMORY; break; } context->cipherInfo = pubKey; context->update = (PK11Cipher) (pMechanism->mechanism == CKM_RSA_X_509 ? RSA_EncryptRaw : RSA_EncryptBlock); context->destroy = pk11_Null; 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); if (att == NULL) { crv = CKR_KEY_HANDLE_INVALID; break; } 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_Encrypt; 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_Encrypt; 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); if (att == NULL) { crv = CKR_KEY_HANDLE_INVALID; break; } context->cipherInfo = RC4_CreateContext((unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); pk11_FreeAttribute(att); if (context->cipherInfo == NULL) { crv = CKR_HOST_MEMORY; /* WRONG !!! */ break; } context->update = (PK11Cipher) RC4_Encrypt; 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_TRUE); pk11_FreeAttribute(att); if (context->cipherInfo == NULL) { crv = CKR_HOST_MEMORY; break; } context->update = (PK11Cipher) DES_Encrypt; 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_EncryptInit initializes an encryption operation. */CK_RV NSC_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey){ return pk11_EncryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT, PK11_ENCRYPT);}/* NSC_EncryptUpdate continues a multiple-part encryption operation. */CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen){ PK11SessionContext *context; unsigned int outlen,i; unsigned int padoutlen = 0; unsigned int maxout = *pulEncryptedPartLen; CK_RV crv; SECStatus rv; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,PR_TRUE,NULL); if (crv != CKR_OK) return crv; /* do padding */ if (context->doPad) { /* deal with previous buffered data */ if (context->padDataLength != 0) { /* fill in the padded to a full block size */ for (i=context->padDataLength; (ulPartLen != 0) && i < context->blockSize; i++) { context->padBuf[i] = *pPart++; ulPartLen--; context->padDataLength++; } /* not enough data to encrypt yet? then return */ if (context->padDataLength != context->blockSize) { *pulEncryptedPartLen = 0; return CKR_OK; } /* encrypt the current padded data */ rv = (*context->update)(context->cipherInfo,pEncryptedPart, &outlen,context->blockSize,context->padBuf,context->blockSize); if (rv != SECSuccess) return CKR_DEVICE_ERROR; pEncryptedPart += padoutlen; maxout -= padoutlen; } /* save the residual */ context->padDataLength = ulPartLen % context->blockSize; if (context->padDataLength) { PORT_Memcpy(context->padBuf, &pPart[ulPartLen-context->padDataLength], context->padDataLength); ulPartLen -= context->padDataLength; } /* if we've exhausted our new buffer, we're done */ if (ulPartLen == 0) { *pulEncryptedPartLen = padoutlen; return CKR_OK; } } /* do it: NOTE: this assumes buf size in is >= buf size out! */ rv = (*context->update)(context->cipherInfo,pEncryptedPart, &outlen, maxout, pPart, ulPartLen); *pulEncryptedPartLen = (CK_ULONG) (outlen + padoutlen); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;}/* NSC_EncryptFinal finishes a multiple-part encryption operation. */CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen){ PK11Session *session; PK11SessionContext *context; unsigned int outlen,i; unsigned int maxout = *pulLastEncryptedPartLen; CK_RV crv; SECStatus rv = SECSuccess; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,PR_TRUE,&session); if (crv != CKR_OK) return crv; *pulLastEncryptedPartLen = 0; /* do padding */ if (context->doPad) { unsigned char padbyte = (unsigned char) (context->blockSize - context->padDataLength); /* fill out rest of pad buffer with pad magic*/ for (i=context->padDataLength; i < context->blockSize; i++) { context->padBuf[i] = padbyte; } rv = (*context->update)(context->cipherInfo,pLastEncryptedPart, &outlen, maxout, context->padBuf, context->blockSize); if (rv == SECSuccess) *pulLastEncryptedPartLen = (CK_ULONG) outlen; } /* do it */ pk11_SetContextByType(session, PK11_ENCRYPT, NULL); pk11_FreeContext(context); pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;}/* NSC_Encrypt encrypts single-part data. */CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen){ PK11Session *session; PK11SessionContext *context; unsigned int outlen; unsigned int maxoutlen = *pulEncryptedDataLen; CK_RV crv; CK_RV crv2; SECStatus rv; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,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_EncryptUpdate(hSession,pData,ulDataLen,pEncryptedData, pulEncryptedDataLen); if (crv != CKR_OK) *pulEncryptedDataLen = 0; maxoutlen -= *pulEncryptedDataLen; pEncryptedData += *pulEncryptedDataLen; finalLen = maxoutlen; crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen); if (crv2 == CKR_OK) { *pulEncryptedDataLen += finalLen; } return crv == CKR_OK ? crv2 :crv; } /* do it: NOTE: this assumes buf size is big enough. */ rv = (*context->update)(context->cipherInfo, pEncryptedData, &outlen, maxoutlen, pData, ulDataLen); *pulEncryptedDataLen = (CK_ULONG) outlen;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?