VirtualBox

Changeset 94627 in vbox for trunk


Ignore:
Timestamp:
Apr 19, 2022 10:12:04 AM (3 years ago)
Author:
vboxsync
Message:

Runtime/crypto: Add additional APIs and supported algorithms for symmetric enc-/decryption, bugref:9955

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/crypto/cipher.h

    r93115 r94627  
    5353/** Nil symmetric cipher handle. */
    5454#define NIL_RTCRCIPHER          ((RTCRCIPHER)0)
     55/** Symmetric cipher context */
     56typedef struct RTCRCIPHERCTXINT *RTCRCIPHERCTX;
     57/** Pointer to a symmetric cipher context */
     58typedef RTCRCIPHERCTX          *PRTCRCIPHERCTX;
     59/** Nil symmetric cipher context */
     60#define NIL_RTCRCIPHERCTX       ((RTCRCIPHERCTX)0)
    5561
    5662/**
     
    6773    /** XTS-AES-256 (NIST SP 800-38E). */
    6874    RTCRCIPHERTYPE_XTS_AES_256,
     75    /** GCM-AES-128. */
     76    RTCRCIPHERTYPE_GCM_AES_128,
     77    /** GCM-AES-256. */
     78    RTCRCIPHERTYPE_GCM_AES_256,
     79    /* CTR-AES-128 */
     80    RTCRCIPHERTYPE_CTR_AES_128,
     81    /* CTR-AES-256 */
     82    RTCRCIPHERTYPE_CTR_AES_256,
    6983    /** End of valid symmetric cipher types. */
    7084    RTCRCIPHERTYPE_END,
     
    8195RTDECL(uint32_t) RTCrCipherGetBlockSize(RTCRCIPHER hCipher);
    8296
     97RTDECL(int) RTCrCipherCtxFree(RTCRCIPHERCTX phCipherCtx);
     98
     99RTDECL(int) RTCrCipherCtxEncryptInit(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     100                                     void const *pvInitVector, size_t cbInitVector,
     101                                     void const *pvAuthData, size_t cbAuthData,
     102                                     PRTCRCIPHERCTX phCipherCtx);
     103RTDECL(int) RTCrCipherCtxEncryptProcess(RTCRCIPHERCTX hCipherCtx, void const *pvPlainText, size_t cbPlainText,
     104                                        void *pvEncrypted, size_t cbEncrypted, size_t *pcbEncrypted);
     105RTDECL(int) RTCrCipherCtxEncryptFinish(RTCRCIPHERCTX hCipherCtx,
     106                                       void *pvEncrypted, size_t *pcbEncrypted,
     107                                       void *pvTag, size_t cbTag, size_t *pcbTag);
     108
     109RTDECL(int) RTCrCipherCtxDecryptInit(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     110                                     void const *pvInitVector, size_t cbInitVector,
     111                                     void const *pvAuthData, size_t cbAuthData,
     112                                     void *pvTag, size_t cbTag, PRTCRCIPHERCTX phCipherCtx);
     113RTDECL(int) RTCrCipherCtxDecryptProcess(RTCRCIPHERCTX hCipherCtx,
     114                                        void const *pvEncrypted, size_t cbEncrypted,
     115                                        void *pvPlainText, size_t cbPlainText, size_t *pcbPlainText);
     116RTDECL(int) RTCrCipherCtxDecryptFinish(RTCRCIPHERCTX hCipherCtx,
     117                                       void *pvPlainText, size_t *pcbPlainText);
     118
     119
    83120RTDECL(int) RTCrCipherEncrypt(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
    84121                              void const *pvInitVector, size_t cbInitVector,
     
    89126                              void const *pvEncrypted, size_t cbEncrypted,
    90127                              void *pvPlainText, size_t cbPlainText, size_t *pcbPlainText);
     128RTDECL(int) RTCrCipherEncryptEx(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     129                                void const *pvInitVector, size_t cbInitVector,
     130                                void const *pvAuthData, size_t cbAuthData,
     131                                void const *pvPlainText, size_t cbPlainText,
     132                                void *pvEncrypted, size_t cbEncrypted, size_t *pcbEncrypted,
     133                                void *pvTag, size_t cbTag, size_t *pcbTag);
     134RTDECL(int) RTCrCipherDecryptEx(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     135                                void const *pvInitVector, size_t cbInitVector,
     136                                void const *pvAuthData, size_t cbAuthData,
     137                                void *pvTag, size_t cbTag,
     138                                void const *pvEncrypted, size_t cbEncrypted,
     139                                void *pvPlainText, size_t cbPlainText, size_t *pcbPlainText);
    91140
    92141/** @} */
  • trunk/include/iprt/err.h

    r93684 r94627  
    27052705/** Invalid initialization vector length. */
    27062706#define VERR_CR_CIPHER_INVALID_INITIALIZATION_VECTOR_LENGTH     (-25808)
     2707/** Invalid tag length. */
     2708#define VERR_CR_CIPHER_INVALID_TAG_LENGTH                       (-25809)
     2709/** EVP_CIPHER_CTX_ctrl EVP_CTRL_AEAD_GET_TAG failed. */
     2710#define VERR_CR_CIPHER_OSSL_GET_TAG_FAILED                      (-25810)
     2711/** EVP_CIPHER_CTX_ctrl EVP_CTRL_AEAD_SET_TAG failed. */
     2712#define VERR_CR_CIPHER_OSSL_SET_TAG_FAILED                      (-25811)
    27072713/** @} */
    27082714
  • trunk/include/iprt/mangling.h

    r94511 r94627  
    34063406# define RTCrCipherRetain                               RT_MANGLER(RTCrCipherRetain)
    34073407# define RTCrCipherRelease                              RT_MANGLER(RTCrCipherRelease)
     3408# define RTCrCipherCtxFree                              RT_MANGLER(RTCrCipherCtxFree)
     3409# define RTCrCipherCtxDecryptInit                       RT_MANGLER(RTCrCipherCtxDecryptInit)
     3410# define RTCrCipherCtxDecryptFinish                     RT_MANGLER(RTCrCipherCtxDecryptFinish)
     3411# define RTCrCipherCtxDecryptProcess                    RT_MANGLER(RTCrCipherCtxDecryptProcess)
     3412# define RTCrCipherCtxEncryptInit                       RT_MANLGER(RTCrCipherCtxEncryptInit)
     3413# define RTCrCipherCtxEncryptFinish                     RT_MANGLER(RTCrCipherCtxEncryptFinish)
     3414# define RTCrCipherCtxEncryptProcess                    RT_MANGLER(RTCrCipherCtxEncryptProcess)
     3415# define RTCrCipherDecrypt                              RT_MANGLER(RTCrCipherDecrypt)
     3416# define RTCrCipherDecryptEx                            RT_MANGLER(RTCrCipherDecryptEx)
     3417# define RTCrCipherEncrypt                              RT_MANGLER(RTCrCipherEncrypt)
     3418# define RTCrCipherEncryptEx                            RT_MANGLER(RTCrCipherEncryptEx)
    34083419# define RTCrDigestClone                                RT_MANGLER(RTCrDigestClone)
    34093420# define RTCrDigestCreate                               RT_MANGLER(RTCrDigestCreate)
  • trunk/src/VBox/Runtime/common/crypto/cipher-openssl.cpp

    r93115 r94627  
    6666
    6767
     68/**
     69 * OpenSSL cipher context data
     70 */
     71typedef struct RTCRCIPHERCTXINT
     72{
     73    /** Pointer to cipher instance data */
     74    RTCRCIPHERINT      *phCipher;
     75    /** Pointer to cipher context */
     76    EVP_CIPHER_CTX     *pCipherCtx;
     77    /** Is decryption */
     78    bool                fDecryption;
     79} RTCRCIPHERCTXINT;
     80
     81
    6882RTDECL(int) RTCrCipherOpenByType(PRTCRCIPHER phCipher, RTCRCIPHERTYPE enmType, uint32_t fFlags)
    6983{
     
    8498            pCipher = EVP_aes_256_xts();
    8599            break;
     100        case RTCRCIPHERTYPE_GCM_AES_128:
     101            pCipher = EVP_aes_128_gcm();
     102            break;
     103        case RTCRCIPHERTYPE_GCM_AES_256:
     104            pCipher = EVP_aes_256_gcm();
     105            break;
     106        case RTCRCIPHERTYPE_CTR_AES_128:
     107            pCipher = EVP_aes_128_ctr();
     108            break;
     109        case RTCRCIPHERTYPE_CTR_AES_256:
     110            pCipher = EVP_aes_256_ctr();
     111            break;
    86112
    87113        /* no default! */
     
    180206
    181207
    182 RTDECL(int) RTCrCipherEncrypt(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
    183                               void const *pvInitVector, size_t cbInitVector,
    184                               void const *pvPlainText, size_t cbPlainText,
    185                               void *pvEncrypted, size_t cbEncrypted, size_t *pcbEncrypted)
    186 {
    187     /*
     208RTDECL(int) RTCrCipherCtxFree(RTCRCIPHERCTX hCipherCtx)
     209{
     210    AssertReturn(hCipherCtx, VERR_INVALID_PARAMETER);
     211    RTCRCIPHERCTXINT *pCtx = hCipherCtx;
     212
     213# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
     214        EVP_CIPHER_CTX_free(pCtx->pCipherCtx);
     215# else
     216        EVP_CIPHER_CTX_cleanup(pCtx->pCipherCtx);
     217        RTMemFree(pCtx->pCipherCtx);
     218# endif
     219        RTMemFree(pCtx);
     220
     221    return VINF_SUCCESS;
     222}
     223
     224
     225RTDECL(int) RTCrCipherCtxEncryptInit(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     226                                     void const *pvInitVector, size_t cbInitVector,
     227                                     void const *pvAuthData, size_t cbAuthData,
     228                                     PRTCRCIPHERCTX phCipherCtx)
     229{
     230     /*
    188231     * Validate input.
    189232     */
     
    197240                    ("%zu, expected %d\n", cbInitVector, EVP_CIPHER_iv_length(pThis->pCipher)),
    198241                    VERR_CR_CIPHER_INVALID_INITIALIZATION_VECTOR_LENGTH);
    199     AssertReturn(cbPlainText > 0, VERR_NO_DATA);
    200242
    201243    Assert(EVP_CIPHER_block_size(pThis->pCipher) <= 1); /** @todo more complicated ciphers later */
    202     size_t const cbNeeded = cbPlainText;
    203     if (pcbEncrypted)
    204     {
    205         *pcbEncrypted = cbNeeded;
    206         AssertReturn(cbEncrypted >= cbNeeded, VERR_BUFFER_OVERFLOW);
    207     }
    208     else
    209         AssertReturn(cbEncrypted == cbNeeded, VERR_INVALID_PARAMETER);
    210     AssertReturn((size_t)(int)cbPlainText == cbPlainText && (int)cbPlainText > 0, VERR_OUT_OF_RANGE);
    211244
    212245    /*
     
    214247     */
    215248    int rc = VERR_NO_MEMORY;
     249    /*
     250     * Create the instance.
     251     */
     252    RTCRCIPHERCTXINT *pCtx = (RTCRCIPHERCTXINT *)RTMemAlloc(sizeof(RTCRCIPHERCTXINT));
     253    if (pCtx)
     254    {
     255        pCtx->phCipher = hCipher;
     256        pCtx->fDecryption = false;
    216257# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
    217     EVP_CIPHER_CTX *pCipherCtx = EVP_CIPHER_CTX_new();
    218     if (pCipherCtx)
     258        pCtx->pCipherCtx = EVP_CIPHER_CTX_new();
     259        if (pCtx->pCipherCtx)
    219260# else
    220     EVP_CIPHER_CTX  CipherCtx;
    221     EVP_CIPHER_CTX *pCipherCtx = &CipherCtx;
    222     RT_ZERO(CipherCtx);
     261        pCtx->pCipherCtx = (EVP_CIPHER_CTX *)RTMemAllocZ(sizeof(EVP_CIPHER_CTX));
    223262# endif
    224     {
    225         int rcOssl = EVP_EncryptInit(pCipherCtx, pThis->pCipher, (unsigned char const *)pvKey,
    226                                      (unsigned char const *)pvInitVector);
    227         if (rcOssl > 0)
    228263        {
    229             /*
    230              * Do the encryption.
    231              */
    232             int cbEncrypted1 = 0;
    233             rcOssl = EVP_EncryptUpdate(pCipherCtx, (unsigned char *)pvEncrypted, &cbEncrypted1,
    234                                        (unsigned char const *)pvPlainText, (int)cbPlainText);
    235             if (rcOssl > 0)
     264            if (EVP_EncryptInit(pCtx->pCipherCtx, pCtx->phCipher->pCipher, (unsigned char const *)pvKey,
     265                                (unsigned char const *)pvInitVector))
    236266            {
    237                 Assert(cbEncrypted1 <= (ssize_t)cbNeeded);
    238                 int cbEncrypted2 = 0;
    239                 rcOssl = EVP_EncryptFinal(pCipherCtx, (unsigned char *)pvEncrypted + cbEncrypted1, &cbEncrypted2);
    240                 if (rcOssl > 0)
     267                if (pvAuthData && cbAuthData)
    241268                {
    242                     Assert(cbEncrypted1 + cbEncrypted2 == (ssize_t)cbNeeded);
    243                     if (pcbEncrypted)
    244                         *pcbEncrypted = cbEncrypted1 + cbEncrypted2;
    245                     rc = VINF_SUCCESS;
     269                    /* Add auth data. */
     270                    int cbEncryptedAuth = 0;
     271                    rc = EVP_EncryptUpdate(pCtx->pCipherCtx, NULL, &cbEncryptedAuth,
     272                                           (unsigned char const *)pvAuthData, (int)cbAuthData) ? VINF_SUCCESS
     273                         : VERR_CR_CIPHER_OSSL_ENCRYPT_UPDATE_FAILED;
    246274                }
    247275                else
    248                     rc = VERR_CR_CIPHER_OSSL_ENCRYPT_FINAL_FAILED;
     276                    rc = VINF_SUCCESS;
    249277            }
    250278            else
    251                 rc = VERR_CR_CIPHER_OSSL_ENCRYPT_UPDATE_FAILED;
     279                rc = VERR_CR_CIPHER_OSSL_ENCRYPT_INIT_FAILED;
     280        }
     281    }
     282
     283    if (RT_SUCCESS(rc))
     284        *phCipherCtx = pCtx;
     285    else
     286        RTCrCipherCtxFree(pCtx);
     287    return rc;
     288}
     289
     290
     291RTDECL(int) RTCrCipherCtxEncryptProcess(RTCRCIPHERCTX hCipherCtx, void const *pvPlainText, size_t cbPlainText,
     292                                        void *pvEncrypted, size_t cbEncrypted, size_t *pcbEncrypted)
     293{
     294    AssertReturn(hCipherCtx, VERR_INVALID_PARAMETER);
     295    AssertReturn(cbPlainText > 0, VERR_NO_DATA);
     296    AssertReturn((size_t)(int)cbPlainText == cbPlainText && (int)cbPlainText > 0, VERR_OUT_OF_RANGE);
     297    AssertReturn(cbEncrypted >= cbPlainText, VERR_BUFFER_OVERFLOW);
     298
     299    RTCRCIPHERCTXINT *pCtx = hCipherCtx;
     300    AssertReturn(!pCtx->fDecryption, VERR_INVALID_STATE);
     301    int cbEncrypted1 = 0;
     302    int rc = VERR_CR_CIPHER_OSSL_ENCRYPT_UPDATE_FAILED;
     303    if (EVP_EncryptUpdate(pCtx->pCipherCtx, (unsigned char *)pvEncrypted, &cbEncrypted1,
     304                          (unsigned char const *)pvPlainText, (int)cbPlainText))
     305    {
     306        *pcbEncrypted = cbEncrypted1;
     307        rc = VINF_SUCCESS;
     308    }
     309    return rc;
     310}
     311
     312
     313RTDECL(int) RTCrCipherCtxEncryptFinish(RTCRCIPHERCTX hCipherCtx,
     314                                       void *pvEncrypted, size_t *pcbEncrypted,
     315                                       void *pvTag, size_t cbTag, size_t *pcbTag)
     316{
     317    AssertReturn(hCipherCtx, VERR_INVALID_PARAMETER);
     318    RTCRCIPHERCTXINT *pCtx = hCipherCtx;
     319    AssertReturn(!pCtx->fDecryption, VERR_INVALID_STATE);
     320    AssertReturn(!pvTag || (pvTag && cbTag == 16), VERR_CR_CIPHER_INVALID_TAG_LENGTH);
     321    int cbEncrypted2 = 0;
     322    int rc = VERR_CR_CIPHER_OSSL_ENCRYPT_FINAL_FAILED;
     323    if (EVP_EncryptFinal(pCtx->pCipherCtx, (uint8_t *)pvEncrypted, &cbEncrypted2))
     324    {
     325        if (pvTag && cbTag)
     326        {
     327            if (EVP_CIPHER_CTX_ctrl(pCtx->pCipherCtx, EVP_CTRL_AEAD_GET_TAG, (int)cbTag, pvTag))
     328            {
     329                *pcbTag = cbTag;
     330                rc = VINF_SUCCESS;
     331            }
     332            else
     333                rc = VERR_CR_CIPHER_OSSL_GET_TAG_FAILED;
    252334        }
    253335        else
    254             rc = VERR_CR_CIPHER_OSSL_ENCRYPT_INIT_FAILED;
    255 
    256 # if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
    257         EVP_CIPHER_CTX_free(pCipherCtx);
    258 # else
    259         EVP_CIPHER_CTX_cleanup(&CipherCtx);
    260 # endif
    261     }
    262     return rc;
    263 }
    264 
    265 
    266 RTDECL(int) RTCrCipherDecrypt(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
    267                               void const *pvInitVector, size_t cbInitVector,
    268                               void const *pvEncrypted, size_t cbEncrypted,
    269                               void *pvPlainText, size_t cbPlainText, size_t *pcbPlainText)
     336            rc = VINF_SUCCESS;
     337
     338        if (RT_SUCCESS(rc) && pcbEncrypted)
     339            *pcbEncrypted = cbEncrypted2;
     340    }
     341
     342    return rc;
     343}
     344
     345
     346RTDECL(int) RTCrCipherCtxDecryptInit(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     347                                     void const *pvInitVector, size_t cbInitVector,
     348                                     void const *pvAuthData, size_t cbAuthData,
     349                                     void *pvTag, size_t cbTag, PRTCRCIPHERCTX phCipherCtx)
    270350{
    271351    /*
     
    281361                    ("%zu, expected %d\n", cbInitVector, EVP_CIPHER_iv_length(pThis->pCipher)),
    282362                    VERR_CR_CIPHER_INVALID_INITIALIZATION_VECTOR_LENGTH);
    283     AssertReturn(cbPlainText > 0, VERR_NO_DATA);
     363    AssertReturn(!pvTag || (pvTag && cbTag == 16), VERR_CR_CIPHER_INVALID_TAG_LENGTH);
    284364
    285365    Assert(EVP_CIPHER_block_size(pThis->pCipher) <= 1); /** @todo more complicated ciphers later */
     366
     367    /*
     368     * Allocate and initialize the cipher context.
     369     */
     370    int rc = VERR_NO_MEMORY;
     371    /*
     372     * Create the instance.
     373     */
     374    RTCRCIPHERCTXINT *pCtx = (RTCRCIPHERCTXINT *)RTMemAlloc(sizeof(RTCRCIPHERCTXINT));
     375    if (pCtx)
     376    {
     377        pCtx->phCipher = hCipher;
     378        pCtx->fDecryption = true;
     379# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
     380        pCtx->pCipherCtx = EVP_CIPHER_CTX_new();
     381# else
     382        pCtx->pCipherCtx = (EVP_CIPHER_CTX *)RTMemAllocZ(sizeof(EVP_CIPHER_CTX));
     383# endif
     384
     385        if (EVP_DecryptInit(pCtx->pCipherCtx, pThis->pCipher, (unsigned char const *)pvKey,
     386                            (unsigned char const *)pvInitVector))
     387        {
     388            rc = VINF_SUCCESS;
     389            if (pvTag && cbTag && !EVP_CIPHER_CTX_ctrl(pCtx->pCipherCtx, EVP_CTRL_AEAD_SET_TAG, (int)cbTag, pvTag))
     390                rc = VERR_CR_CIPHER_OSSL_SET_TAG_FAILED;
     391
     392            if (RT_SUCCESS(rc) && pvAuthData && cbAuthData)
     393            {
     394                /* Add auth data. */
     395                int cbDecryptedAuth = 0;
     396                if (!EVP_DecryptUpdate(pCtx->pCipherCtx, NULL, &cbDecryptedAuth,
     397                                        (unsigned char const *)pvAuthData, (int)cbAuthData))
     398                    rc = VERR_CR_CIPHER_OSSL_DECRYPT_UPDATE_FAILED;
     399            }
     400        }
     401        else
     402            rc = VERR_CR_CIPHER_OSSL_DECRYPT_INIT_FAILED;
     403    }
     404
     405    if (RT_SUCCESS(rc))
     406        *phCipherCtx = pCtx;
     407    else
     408        RTCrCipherCtxFree(pCtx);
     409
     410    return rc;
     411}
     412
     413
     414RTDECL(int) RTCrCipherCtxDecryptProcess(RTCRCIPHERCTX hCipherCtx,
     415                                        void const *pvEncrypted, size_t cbEncrypted,
     416                                        void *pvPlainText, size_t cbPlainText, size_t *pcbPlainText)
     417{
     418    AssertReturn(hCipherCtx, VERR_INVALID_PARAMETER);
     419    AssertReturn(cbEncrypted > 0, VERR_NO_DATA);
     420    AssertReturn((size_t)(int)cbEncrypted == cbEncrypted && (int)cbEncrypted > 0, VERR_OUT_OF_RANGE);
     421    AssertReturn(cbPlainText >= cbEncrypted, VERR_BUFFER_OVERFLOW);
     422
     423    RTCRCIPHERCTXINT *pCtx = hCipherCtx;
     424    AssertReturn(pCtx->fDecryption, VERR_INVALID_STATE);
     425    int rc = VERR_CR_CIPHER_OSSL_DECRYPT_UPDATE_FAILED;
     426    int cbDecrypted1 = 0;
     427    if (EVP_DecryptUpdate(pCtx->pCipherCtx, (unsigned char *)pvPlainText, &cbDecrypted1,
     428                          (unsigned char const *)pvEncrypted, (int)cbEncrypted))
     429    {
     430        *pcbPlainText = cbDecrypted1;
     431        rc = VINF_SUCCESS;
     432    }
     433    return rc;
     434}
     435
     436
     437RTDECL(int) RTCrCipherCtxDecryptFinish(RTCRCIPHERCTX hCipherCtx,
     438                                       void *pvPlainText, size_t *pcbPlainText)
     439{
     440    AssertReturn(hCipherCtx, VERR_INVALID_PARAMETER);
     441    RTCRCIPHERCTXINT *pCtx = hCipherCtx;
     442    AssertReturn(pCtx->fDecryption, VERR_INVALID_STATE);
     443    int cbDecrypted2 = 0;
     444    int rc = VERR_CR_CIPHER_OSSL_ENCRYPT_FINAL_FAILED;
     445    if (EVP_DecryptFinal(pCtx->pCipherCtx, (uint8_t *)pvPlainText, &cbDecrypted2))
     446    {
     447        rc = VINF_SUCCESS;
     448        if (pcbPlainText)
     449            *pcbPlainText = cbDecrypted2;
     450    }
     451
     452    return rc;
     453}
     454
     455
     456RTDECL(int) RTCrCipherEncrypt(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     457                              void const *pvInitVector, size_t cbInitVector,
     458                              void const *pvPlainText, size_t cbPlainText,
     459                              void *pvEncrypted, size_t cbEncrypted, size_t *pcbEncrypted)
     460{
     461    return RTCrCipherEncryptEx(hCipher, pvKey, cbKey, pvInitVector, cbInitVector,
     462                               NULL, 0, pvPlainText, cbPlainText, pvEncrypted, cbEncrypted,
     463                               pcbEncrypted, NULL, 0, NULL);
     464}
     465
     466
     467RTDECL(int) RTCrCipherDecrypt(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     468                              void const *pvInitVector, size_t cbInitVector,
     469                              void const *pvEncrypted, size_t cbEncrypted,
     470                              void *pvPlainText, size_t cbPlainText, size_t *pcbPlainText)
     471{
     472    return RTCrCipherDecryptEx(hCipher, pvKey, cbKey, pvInitVector, cbInitVector,
     473                               NULL, 0, NULL, 0, pvEncrypted, cbEncrypted,
     474                               pvPlainText, cbPlainText, pcbPlainText);
     475}
     476
     477
     478RTDECL(int) RTCrCipherEncryptEx(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     479                                void const *pvInitVector, size_t cbInitVector,
     480                                void const *pvAuthData, size_t cbAuthData,
     481                                void const *pvPlainText, size_t cbPlainText,
     482                                void *pvEncrypted, size_t cbEncrypted, size_t *pcbEncrypted,
     483                                void *pvTag, size_t cbTag, size_t *pcbTag)
     484{
     485    size_t const cbNeeded = cbPlainText;
     486    if (pcbEncrypted)
     487    {
     488        *pcbEncrypted = cbNeeded;
     489        AssertReturn(cbEncrypted >= cbNeeded, VERR_BUFFER_OVERFLOW);
     490    }
     491    else
     492        AssertReturn(cbEncrypted == cbNeeded, VERR_INVALID_PARAMETER);
     493    AssertReturn((size_t)(int)cbPlainText == cbPlainText && (int)cbPlainText > 0, VERR_OUT_OF_RANGE);
     494
     495    RTCRCIPHERCTXINT *pCtx = NIL_RTCRCIPHERCTX;
     496
     497    int rc = RTCrCipherCtxEncryptInit(hCipher, pvKey, cbKey, pvInitVector, cbInitVector,
     498                                      pvAuthData, cbAuthData, &pCtx);
     499    if (RT_SUCCESS(rc))
     500    {
     501        size_t cbEncrypted1 = 0;
     502        rc = RTCrCipherCtxEncryptProcess(pCtx, pvPlainText, cbPlainText, pvEncrypted, cbEncrypted, &cbEncrypted1);
     503        if (RT_SUCCESS(rc))
     504        {
     505            size_t cbEncrypted2 = 0;
     506            rc = RTCrCipherCtxEncryptFinish(pCtx, (unsigned char *)pvEncrypted + cbEncrypted1,
     507                                            &cbEncrypted2, pvTag, cbTag, pcbTag);
     508            if (RT_SUCCESS(rc))
     509            {
     510                Assert(cbEncrypted1 + cbEncrypted2 == cbNeeded);
     511                if (pcbEncrypted)
     512                    *pcbEncrypted = cbEncrypted1 + cbEncrypted2;
     513            }
     514        }
     515    }
     516
     517    if (pCtx != NIL_RTCRCIPHERCTX)
     518        RTCrCipherCtxFree(pCtx);
     519
     520    return rc;
     521}
     522
     523
     524RTDECL(int) RTCrCipherDecryptEx(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey,
     525                                void const *pvInitVector, size_t cbInitVector,
     526                                void const *pvAuthData, size_t cbAuthData,
     527                                void *pvTag, size_t cbTag,
     528                                void const *pvEncrypted, size_t cbEncrypted,
     529                                void *pvPlainText, size_t cbPlainText, size_t *pcbPlainText)
     530{
    286531    size_t const cbNeeded = cbEncrypted;
    287532    if (pcbPlainText)
     
    294539    AssertReturn((size_t)(int)cbEncrypted == cbEncrypted && (int)cbEncrypted > 0, VERR_OUT_OF_RANGE);
    295540
    296     /*
    297      * Allocate and initialize the cipher context.
    298      */
    299     int rc = VERR_NO_MEMORY;
    300 # if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
    301     EVP_CIPHER_CTX *pCipherCtx = EVP_CIPHER_CTX_new();
    302     if (pCipherCtx)
    303 # else
    304     EVP_CIPHER_CTX  CipherCtx;
    305     EVP_CIPHER_CTX *pCipherCtx = &CipherCtx;
    306     RT_ZERO(CipherCtx);
    307 # endif
    308     {
    309         int rcOssl = EVP_DecryptInit(pCipherCtx, pThis->pCipher, (unsigned char const *)pvKey,
    310                                      (unsigned char const *)pvInitVector);
    311         if (rcOssl > 0)
     541    RTCRCIPHERCTXINT *pCtx = NIL_RTCRCIPHERCTX;
     542
     543    int rc = RTCrCipherCtxDecryptInit(hCipher, pvKey, cbKey, pvInitVector, cbInitVector,
     544                                      pvAuthData, cbAuthData, pvTag, cbTag, &pCtx);
     545    if (RT_SUCCESS(rc))
     546    {
     547        size_t cbDecrypted1 = 0;
     548        rc = RTCrCipherCtxDecryptProcess(pCtx, pvEncrypted, cbEncrypted, pvPlainText, cbPlainText, &cbDecrypted1);
     549        if (RT_SUCCESS(rc))
    312550        {
    313             /*
    314              * Do the decryption.
    315              */
    316             int cbDecrypted1 = 0;
    317             rcOssl = EVP_DecryptUpdate(pCipherCtx, (unsigned char *)pvPlainText, &cbDecrypted1,
    318                                        (unsigned char const *)pvEncrypted, (int)cbEncrypted);
    319             if (rcOssl > 0)
     551            size_t cbDecrypted2 = 0;
     552            rc = RTCrCipherCtxDecryptFinish(pCtx, (unsigned char *)pvPlainText + cbDecrypted1,
     553                                            &cbDecrypted2);
     554            if (RT_SUCCESS(rc))
    320555            {
    321                 Assert(cbDecrypted1 <= (ssize_t)cbNeeded);
    322                 int cbDecrypted2 = 0;
    323                 rcOssl = EVP_DecryptFinal(pCipherCtx, (unsigned char *)pvPlainText + cbDecrypted1, &cbDecrypted2);
    324                 if (rcOssl > 0)
    325                 {
    326                     Assert(cbDecrypted1 + cbDecrypted2 == (ssize_t)cbNeeded);
    327                     if (pcbPlainText)
    328                         *pcbPlainText = cbDecrypted1 + cbDecrypted2;
    329                     rc = VINF_SUCCESS;
    330                 }
    331                 else
    332                     rc = VERR_CR_CIPHER_OSSL_DECRYPT_FINAL_FAILED;
     556                Assert(cbDecrypted1 + cbDecrypted2 == cbNeeded);
     557                if (pcbPlainText)
     558                    *pcbPlainText = cbDecrypted1 + cbDecrypted2;
    333559            }
    334             else
    335                 rc = VERR_CR_CIPHER_OSSL_DECRYPT_UPDATE_FAILED;
    336560        }
    337         else
    338             rc = VERR_CR_CIPHER_OSSL_DECRYPT_INIT_FAILED;
    339 
    340 # if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
    341         EVP_CIPHER_CTX_free(pCipherCtx);
    342 # else
    343         EVP_CIPHER_CTX_cleanup(&CipherCtx);
    344 # endif
    345     }
     561    }
     562
     563    if (pCtx != NIL_RTCRCIPHERCTX)
     564        RTCrCipherCtxFree(pCtx);
     565
    346566    return rc;
    347567}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette