VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/crypto/cipher-openssl.cpp@ 94627

最後變更 在這個檔案從94627是 94627,由 vboxsync 提交於 3 年 前

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

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 19.9 KB
 
1/* $Id: cipher-openssl.cpp 94627 2022-04-19 10:12:04Z vboxsync $ */
2/** @file
3 * IPRT - Crypto - Symmetric Cipher using OpenSSL.
4 */
5
6/*
7 * Copyright (C) 2018-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#ifdef IPRT_WITH_OPENSSL
32# include "internal/iprt.h"
33# include <iprt/crypto/cipher.h>
34
35# include <iprt/asm.h>
36# include <iprt/assert.h>
37# include <iprt/err.h>
38# include <iprt/mem.h>
39# include <iprt/string.h>
40
41# include "internal/iprt-openssl.h"
42# include "internal/openssl-pre.h"
43# include <openssl/evp.h>
44# include "internal/openssl-post.h"
45
46# include "internal/magics.h"
47
48
49/*********************************************************************************************************************************
50* Structures and Typedefs *
51*********************************************************************************************************************************/
52/**
53 * OpenSSL cipher instance data.
54 */
55typedef struct RTCRCIPHERINT
56{
57 /** Magic value (RTCRCIPHERINT_MAGIC). */
58 uint32_t u32Magic;
59 /** Reference count. */
60 uint32_t volatile cRefs;
61 /** The cihper. */
62 const EVP_CIPHER *pCipher;
63 /** The IPRT cipher type, if we know it. */
64 RTCRCIPHERTYPE enmType;
65} RTCRCIPHERINT;
66
67
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
82RTDECL(int) RTCrCipherOpenByType(PRTCRCIPHER phCipher, RTCRCIPHERTYPE enmType, uint32_t fFlags)
83{
84 AssertPtrReturn(phCipher, VERR_INVALID_POINTER);
85 *phCipher = NIL_RTCRCIPHER;
86 AssertReturn(!fFlags, VERR_INVALID_FLAGS);
87
88 /*
89 * Translate the IPRT cipher type to EVP cipher.
90 */
91 const EVP_CIPHER *pCipher = NULL;
92 switch (enmType)
93 {
94 case RTCRCIPHERTYPE_XTS_AES_128:
95 pCipher = EVP_aes_128_xts();
96 break;
97 case RTCRCIPHERTYPE_XTS_AES_256:
98 pCipher = EVP_aes_256_xts();
99 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;
112
113 /* no default! */
114 case RTCRCIPHERTYPE_INVALID:
115 case RTCRCIPHERTYPE_END:
116 case RTCRCIPHERTYPE_32BIT_HACK:
117 AssertFailedReturn(VERR_INVALID_PARAMETER);
118 }
119 AssertReturn(pCipher, VERR_CR_CIPHER_NOT_SUPPORTED);
120
121 /*
122 * Create the instance.
123 */
124 RTCRCIPHERINT *pThis = (RTCRCIPHERINT *)RTMemAllocZ(sizeof(*pThis));
125 if (pThis)
126 {
127 pThis->u32Magic = RTCRCIPHERINT_MAGIC;
128 pThis->cRefs = 1;
129 pThis->pCipher = pCipher;
130 pThis->enmType = enmType;
131 *phCipher = pThis;
132 return VINF_SUCCESS;
133 }
134 return VERR_NO_MEMORY;
135}
136
137
138RTDECL(uint32_t) RTCrCipherRetain(RTCRCIPHER hCipher)
139{
140 RTCRCIPHERINT *pThis = hCipher;
141 AssertPtrReturn(pThis, UINT32_MAX);
142 AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, UINT32_MAX);
143
144 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
145 Assert(cRefs > 1 && cRefs < 1024);
146 return cRefs;
147}
148
149
150/**
151 * Destroys the cipher instance.
152 */
153static uint32_t rtCrCipherDestroy(RTCRCIPHER pThis)
154{
155 pThis->u32Magic= ~RTCRCIPHERINT_MAGIC;
156 pThis->pCipher = NULL;
157 RTMemFree(pThis);
158 return 0;
159}
160
161
162RTDECL(uint32_t) RTCrCipherRelease(RTCRCIPHER hCipher)
163{
164 RTCRCIPHERINT *pThis = hCipher;
165 if (pThis == NIL_RTCRCIPHER)
166 return 0;
167 AssertPtrReturn(pThis, UINT32_MAX);
168 AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, UINT32_MAX);
169
170 uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
171 Assert(cRefs < 1024);
172 if (cRefs == 0)
173 return rtCrCipherDestroy(pThis);
174 return cRefs;
175}
176
177
178RTDECL(uint32_t) RTCrCipherGetKeyLength(RTCRCIPHER hCipher)
179{
180 RTCRCIPHERINT *pThis = hCipher;
181 AssertPtrReturn(pThis, 0);
182 AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, 0);
183
184 return EVP_CIPHER_key_length(pThis->pCipher);
185}
186
187
188RTDECL(uint32_t) RTCrCipherGetInitializationVectorLength(RTCRCIPHER hCipher)
189{
190 RTCRCIPHERINT *pThis = hCipher;
191 AssertPtrReturn(pThis, 0);
192 AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, 0);
193
194 return EVP_CIPHER_iv_length(pThis->pCipher);
195}
196
197
198RTDECL(uint32_t) RTCrCipherGetBlockSize(RTCRCIPHER hCipher)
199{
200 RTCRCIPHERINT *pThis = hCipher;
201 AssertPtrReturn(pThis, 0);
202 AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, 0);
203
204 return EVP_CIPHER_block_size(pThis->pCipher);
205}
206
207
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 /*
231 * Validate input.
232 */
233 RTCRCIPHERINT *pThis = hCipher;
234 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
235 AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, VERR_INVALID_HANDLE);
236 AssertMsgReturn((ssize_t)cbKey == EVP_CIPHER_key_length(pThis->pCipher),
237 ("%zu, expected %d\n", cbKey, EVP_CIPHER_key_length(pThis->pCipher)),
238 VERR_CR_CIPHER_INVALID_KEY_LENGTH);
239 AssertMsgReturn((ssize_t)cbInitVector == EVP_CIPHER_iv_length(pThis->pCipher),
240 ("%zu, expected %d\n", cbInitVector, EVP_CIPHER_iv_length(pThis->pCipher)),
241 VERR_CR_CIPHER_INVALID_INITIALIZATION_VECTOR_LENGTH);
242
243 Assert(EVP_CIPHER_block_size(pThis->pCipher) <= 1); /** @todo more complicated ciphers later */
244
245 /*
246 * Allocate and initialize the cipher context.
247 */
248 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;
257# if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
258 pCtx->pCipherCtx = EVP_CIPHER_CTX_new();
259 if (pCtx->pCipherCtx)
260# else
261 pCtx->pCipherCtx = (EVP_CIPHER_CTX *)RTMemAllocZ(sizeof(EVP_CIPHER_CTX));
262# endif
263 {
264 if (EVP_EncryptInit(pCtx->pCipherCtx, pCtx->phCipher->pCipher, (unsigned char const *)pvKey,
265 (unsigned char const *)pvInitVector))
266 {
267 if (pvAuthData && cbAuthData)
268 {
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;
274 }
275 else
276 rc = VINF_SUCCESS;
277 }
278 else
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;
334 }
335 else
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)
350{
351 /*
352 * Validate input.
353 */
354 RTCRCIPHERINT *pThis = hCipher;
355 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
356 AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, VERR_INVALID_HANDLE);
357 AssertMsgReturn((ssize_t)cbKey == EVP_CIPHER_key_length(pThis->pCipher),
358 ("%zu, expected %d\n", cbKey, EVP_CIPHER_key_length(pThis->pCipher)),
359 VERR_CR_CIPHER_INVALID_KEY_LENGTH);
360 AssertMsgReturn((ssize_t)cbInitVector == EVP_CIPHER_iv_length(pThis->pCipher),
361 ("%zu, expected %d\n", cbInitVector, EVP_CIPHER_iv_length(pThis->pCipher)),
362 VERR_CR_CIPHER_INVALID_INITIALIZATION_VECTOR_LENGTH);
363 AssertReturn(!pvTag || (pvTag && cbTag == 16), VERR_CR_CIPHER_INVALID_TAG_LENGTH);
364
365 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{
531 size_t const cbNeeded = cbEncrypted;
532 if (pcbPlainText)
533 {
534 *pcbPlainText = cbNeeded;
535 AssertReturn(cbPlainText >= cbNeeded, VERR_BUFFER_OVERFLOW);
536 }
537 else
538 AssertReturn(cbPlainText == cbNeeded, VERR_INVALID_PARAMETER);
539 AssertReturn((size_t)(int)cbEncrypted == cbEncrypted && (int)cbEncrypted > 0, VERR_OUT_OF_RANGE);
540
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))
550 {
551 size_t cbDecrypted2 = 0;
552 rc = RTCrCipherCtxDecryptFinish(pCtx, (unsigned char *)pvPlainText + cbDecrypted1,
553 &cbDecrypted2);
554 if (RT_SUCCESS(rc))
555 {
556 Assert(cbDecrypted1 + cbDecrypted2 == cbNeeded);
557 if (pcbPlainText)
558 *pcbPlainText = cbDecrypted1 + cbDecrypted2;
559 }
560 }
561 }
562
563 if (pCtx != NIL_RTCRCIPHERCTX)
564 RTCrCipherCtxFree(pCtx);
565
566 return rc;
567}
568
569#endif /* IPRT_WITH_OPENSSL */
570
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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