sftkmessage.c (14037B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* 5 * This file implements PKCS 11 on top of our existing security modules 6 * 7 * Implement the PKCS #11 v3.0 Message interfaces 8 */ 9 #include "seccomon.h" 10 #include "pkcs11.h" 11 #include "pkcs11i.h" 12 #include "blapi.h" 13 #include "prenv.h" 14 #include "softoken.h" 15 16 static SECStatus 17 sftk_ChaCha20_Poly1305_Message_Encrypt(void *vctx, 18 void *cipherText, unsigned int *cipherTextLen, 19 unsigned int maxOutLen, void *plainText, 20 unsigned int plainTextLen, 21 void *vparams, 22 unsigned int paramsLen, void *aad, 23 unsigned int aadLen) 24 { 25 ChaCha20Poly1305Context *ctx = vctx; 26 CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *params = vparams; 27 return ChaCha20Poly1305_Encrypt(ctx, cipherText, cipherTextLen, maxOutLen, 28 plainText, plainTextLen, params->pNonce, params->ulNonceLen, 29 aad, aadLen, params->pTag); 30 } 31 32 static SECStatus 33 sftk_ChaCha20_Poly1305_Message_Decrypt(void *vctx, 34 void *plainText, unsigned int *plainTextLen, 35 unsigned int maxOutLen, void *cipherText, 36 unsigned int cipherTextLen, 37 void *vparams, 38 unsigned int paramsLen, void *aad, 39 unsigned int aadLen) 40 { 41 ChaCha20Poly1305Context *ctx = vctx; 42 CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *params = vparams; 43 return ChaCha20Poly1305_Decrypt(ctx, plainText, plainTextLen, maxOutLen, 44 cipherText, cipherTextLen, params->pNonce, params->ulNonceLen, 45 aad, aadLen, params->pTag); 46 } 47 48 void 49 sftk_ChaCha20Poly1305_DestroyContext(void *vctx, PRBool freeit) 50 { 51 ChaCha20Poly1305Context *ctx = vctx; 52 ChaCha20Poly1305_DestroyContext(ctx, freeit); 53 } 54 55 static SECStatus 56 sftk_AES_AEAD(void *vctx, 57 void *plainText, unsigned int *plainTextLen, 58 unsigned int maxOutLen, void *cipherText, 59 unsigned int cipherTextLen, 60 void *params, 61 unsigned int paramsLen, void *aad, 62 unsigned int aadLen) 63 { 64 AESContext *ctx = vctx; 65 return AES_AEAD(ctx, plainText, plainTextLen, maxOutLen, cipherText, cipherTextLen, params, paramsLen, aad, aadLen); 66 } 67 68 void 69 sftk_AES_DestroyContext(void *ctx, PRBool freeit) 70 { 71 AESContext *actx = ctx; 72 AES_DestroyContext(actx, freeit); 73 } 74 75 /* 76 * Handle AEAD Encryption operation 77 * 78 * The setup is similiar to sftk_CryptInit except we set the aeadUpdate 79 * function instead of the normal update function. This function handles 80 * both the Encrypt case and the Decrypt case. 81 */ 82 static CK_RV 83 sftk_MessageCryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 84 CK_OBJECT_HANDLE hKey, SFTKContextType contextType, 85 CK_ATTRIBUTE_TYPE operation, PRBool encrypt) 86 { 87 SFTKSession *session; 88 SFTKObject *key; 89 SFTKSessionContext *context; 90 SFTKAttribute *att; 91 CK_KEY_TYPE key_type; 92 CK_RV crv = CKR_OK; 93 94 if (!pMechanism) { 95 return CKR_MECHANISM_PARAM_INVALID; 96 } 97 98 crv = sftk_MechAllowsOperation(pMechanism->mechanism, 99 CKA_NSS_MESSAGE | operation); 100 if (crv != CKR_OK) 101 return crv; 102 103 session = sftk_SessionFromHandle(hSession); 104 if (session == NULL) 105 return CKR_SESSION_HANDLE_INVALID; 106 107 crv = sftk_InitGeneric(session, pMechanism, &context, contextType, &key, 108 hKey, &key_type, CKO_SECRET_KEY, operation); 109 if (crv != CKR_OK) { 110 sftk_FreeSession(session); 111 return crv; 112 } 113 114 att = sftk_FindAttribute(key, CKA_VALUE); 115 if (att == NULL) { 116 sftk_FreeSession(session); 117 sftk_FreeContext(context); 118 return CKR_KEY_HANDLE_INVALID; 119 } 120 121 context->doPad = PR_FALSE; 122 context->multi = PR_TRUE; /* All message are 'multi' operations */ 123 124 switch (pMechanism->mechanism) { 125 case CKM_AES_GCM: 126 context->cipherInfo = AES_CreateContext( 127 (unsigned char *)att->attrib.pValue, 128 NULL, NSS_AES_GCM, encrypt, att->attrib.ulValueLen, 129 AES_BLOCK_SIZE); 130 context->aeadUpdate = sftk_AES_AEAD; 131 context->destroy = sftk_AES_DestroyContext; 132 break; 133 case CKM_CHACHA20_POLY1305: 134 context->cipherInfo = ChaCha20Poly1305_CreateContext( 135 (unsigned char *)att->attrib.pValue, att->attrib.ulValueLen, 136 16); 137 context->aeadUpdate = (encrypt ? sftk_ChaCha20_Poly1305_Message_Encrypt : sftk_ChaCha20_Poly1305_Message_Decrypt); 138 context->destroy = sftk_ChaCha20Poly1305_DestroyContext; 139 break; 140 default: 141 crv = CKR_MECHANISM_INVALID; 142 break; 143 } 144 if (context->cipherInfo == NULL) { 145 crv = sftk_MapCryptError(PORT_GetError()); 146 if (crv == CKR_OK) { 147 crv = CKR_GENERAL_ERROR; 148 } 149 } 150 if (crv != CKR_OK) { 151 sftk_FreeContext(context); 152 sftk_FreeSession(session); 153 return crv; 154 } 155 sftk_SetContextByType(session, contextType, context); 156 sftk_FreeSession(session); 157 return CKR_OK; 158 } 159 160 /* 161 * Generic handler for the actual encryption/decryption. Each call handles 162 * The authentication data for the entire block. Multiple calls using 163 * BeginMessage and NextMessage are not supported and CKF_MESSSAGE_MULTI is 164 * not set on the supported algorithms 165 */ 166 static CK_RV 167 sftk_CryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 168 CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, 169 CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pIntext, 170 CK_ULONG ulIntextLen, CK_BYTE_PTR pOuttext, 171 CK_ULONG_PTR pulOuttextLen, SFTKContextType contextType) 172 { 173 SFTKSessionContext *context; 174 unsigned int outlen; 175 unsigned int maxout = *pulOuttextLen; 176 CK_RV crv; 177 SECStatus rv; 178 179 CHECK_FORK(); 180 181 /* make sure we're legal */ 182 crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, NULL); 183 if (crv != CKR_OK) 184 return crv; 185 186 if (!pOuttext) { 187 *pulOuttextLen = ulIntextLen; 188 return CKR_OK; 189 } 190 rv = (*context->aeadUpdate)(context->cipherInfo, pOuttext, &outlen, 191 maxout, pIntext, ulIntextLen, 192 pParameter, ulParameterLen, 193 pAssociatedData, ulAssociatedDataLen); 194 195 if (rv != SECSuccess) { 196 if (contextType == SFTK_MESSAGE_ENCRYPT) { 197 return sftk_MapCryptError(PORT_GetError()); 198 } else { 199 return sftk_MapDecryptError(PORT_GetError()); 200 } 201 } 202 *pulOuttextLen = (CK_ULONG)(outlen); 203 return CKR_OK; 204 } 205 206 /* 207 * Common message cleanup rountine 208 */ 209 static CK_RV 210 sftk_MessageCryptFinal(CK_SESSION_HANDLE hSession, 211 SFTKContextType contextType) 212 { 213 SFTKSession *session; 214 SFTKSessionContext *context; 215 CK_RV crv; 216 217 CHECK_FORK(); 218 219 /* make sure we're legal */ 220 crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, &session); 221 if (crv != CKR_OK) 222 return crv; 223 sftk_TerminateOp(session, contextType, context); 224 sftk_FreeSession(session); 225 return CKR_OK; 226 } 227 228 /* MessageEncrypt and EncryptMessage functions just use the helper functions 229 * above */ 230 CK_RV 231 NSC_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 232 CK_OBJECT_HANDLE hKey) 233 { 234 return sftk_MessageCryptInit(hSession, pMechanism, hKey, 235 SFTK_MESSAGE_ENCRYPT, CKA_ENCRYPT, PR_TRUE); 236 } 237 238 CK_RV 239 NSC_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 240 CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, 241 CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext, 242 CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext, 243 CK_ULONG_PTR pulCiphertextLen) 244 { 245 return sftk_CryptMessage(hSession, pParameter, ulParameterLen, 246 pAssociatedData, ulAssociatedDataLen, pPlaintext, 247 ulPlaintextLen, pCiphertext, pulCiphertextLen, 248 SFTK_MESSAGE_ENCRYPT); 249 } 250 251 /* 252 * We only support the single shot function. The Begin/Next version can be 253 * dealt with if we need to support S/MIME or something. It would probably 254 * just buffer rather then returning intermediate results. 255 */ 256 CK_RV 257 NSC_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 258 CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, 259 CK_ULONG ulAssociatedDataLen) 260 { 261 return CKR_FUNCTION_NOT_SUPPORTED; 262 } 263 264 CK_RV 265 NSC_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 266 CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart, 267 CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart, 268 CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags) 269 { 270 return CKR_FUNCTION_NOT_SUPPORTED; 271 } 272 273 CK_RV 274 NSC_MessageEncryptFinal(CK_SESSION_HANDLE hSession) 275 { 276 return sftk_MessageCryptFinal(hSession, SFTK_MESSAGE_ENCRYPT); 277 } 278 279 /* MessageDecrypt and DecryptMessage functions just use the helper functions 280 * above */ 281 CK_RV 282 NSC_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 283 CK_OBJECT_HANDLE hKey) 284 { 285 return sftk_MessageCryptInit(hSession, pMechanism, hKey, 286 SFTK_MESSAGE_DECRYPT, CKA_DECRYPT, PR_FALSE); 287 } 288 289 CK_RV 290 NSC_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 291 CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, 292 CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext, 293 CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext, 294 CK_ULONG_PTR pulPlaintextLen) 295 { 296 return sftk_CryptMessage(hSession, pParameter, ulParameterLen, 297 pAssociatedData, ulAssociatedDataLen, pCiphertext, 298 ulCiphertextLen, pPlaintext, pulPlaintextLen, 299 SFTK_MESSAGE_DECRYPT); 300 } 301 302 /* 303 * We only support the single shot function. The Begin/Next version can be 304 * dealt with if we need to support S/MIME or something. It would probably 305 * just buffer rather then returning intermediate results. This is expecially 306 * true for decrypt, which isn't supposed to return any data unless it's been 307 * authenticated (which can't happen until the last block is processed). 308 */ 309 CK_RV 310 NSC_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 311 CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, 312 CK_ULONG ulAssociatedDataLen) 313 { 314 return CKR_FUNCTION_NOT_SUPPORTED; 315 } 316 317 CK_RV 318 NSC_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 319 CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart, 320 CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart, 321 CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags) 322 { 323 return CKR_FUNCTION_NOT_SUPPORTED; 324 } 325 326 CK_RV 327 NSC_MessageDecryptFinal(CK_SESSION_HANDLE hSession) 328 { 329 return sftk_MessageCryptFinal(hSession, SFTK_MESSAGE_DECRYPT); 330 } 331 332 /* 333 * There are no mechanisms defined to use the MessageSign and MessageVerify 334 * interfaces yet, so we don't need to implement anything. 335 */ 336 CK_RV 337 NSC_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 338 CK_OBJECT_HANDLE hKey) 339 { 340 return CKR_FUNCTION_NOT_SUPPORTED; 341 } 342 343 CK_RV 344 NSC_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 345 CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen, 346 CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) 347 { 348 return CKR_FUNCTION_NOT_SUPPORTED; 349 } 350 351 CK_RV 352 NSC_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 353 CK_ULONG ulParameterLen) 354 { 355 return CKR_FUNCTION_NOT_SUPPORTED; 356 } 357 358 CK_RV 359 NSC_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 360 CK_ULONG ulParameterLen, CK_BYTE_PTR pData, 361 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 362 CK_ULONG_PTR pulSignatureLen) 363 { 364 return CKR_FUNCTION_NOT_SUPPORTED; 365 } 366 367 CK_RV 368 NSC_MessageSignFinal(CK_SESSION_HANDLE hSession) 369 { 370 return CKR_FUNCTION_NOT_SUPPORTED; 371 } 372 373 CK_RV 374 NSC_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 375 CK_OBJECT_HANDLE hKey) 376 { 377 return CKR_FUNCTION_NOT_SUPPORTED; 378 } 379 380 CK_RV 381 NSC_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 382 CK_ULONG ulParameterLen, CK_BYTE_PTR pData, 383 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 384 CK_ULONG ulSignatureLen) 385 { 386 return CKR_FUNCTION_NOT_SUPPORTED; 387 } 388 389 CK_RV 390 NSC_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 391 CK_ULONG ulParameterLen) 392 { 393 return CKR_FUNCTION_NOT_SUPPORTED; 394 } 395 396 CK_RV 397 NSC_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, 398 CK_ULONG ulParameterLen, CK_BYTE_PTR pData, 399 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 400 CK_ULONG ulSignatureLen) 401 { 402 return CKR_FUNCTION_NOT_SUPPORTED; 403 } 404 405 CK_RV 406 NSC_MessageVerifyFinal(CK_SESSION_HANDLE hSession) 407 { 408 return CKR_FUNCTION_NOT_SUPPORTED; 409 }