tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }