Coverage Report

Created: 2024-11-21 07:03

/src/nss-nspr/nss/lib/freebl/chacha20poly1305.c
Line
Count
Source (jump to first uncovered line)
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
#ifdef FREEBL_NO_DEPEND
6
#include "stubs.h"
7
#endif
8
9
#include <string.h>
10
#include <stdio.h>
11
12
#include "seccomon.h"
13
#include "secerr.h"
14
#include "blapit.h"
15
#include "blapii.h"
16
#include "chacha20poly1305.h"
17
18
// There are three implementations of ChaCha20Poly1305:
19
// 1) 128-bit with AVX hardware acceleration used on x64
20
// 2) 256-bit with AVX2 hardware acceleration used on x64
21
// 3) 32-bit used on all other platforms
22
23
// On x64 when AVX2 and other necessary registers are available,
24
// the 256bit-verctorized version will be used. When AVX2 features
25
// are unavailable or disabled but AVX registers are available, the
26
// 128bit-vectorized version will be used. In all other cases the
27
// scalar version of the HACL* code will be used.
28
29
// Instead of including the headers (they bring other things we don't want),
30
// we declare the functions here.
31
// Usage is guarded by runtime checks of required hardware features.
32
33
// Forward declaration from Hacl_Chacha20_Vec128.h and Hacl_Chacha20Poly1305_128.h.
34
extern void Hacl_Chacha20_Vec128_chacha20_encrypt_128(uint32_t len, uint8_t *out,
35
                                                      uint8_t *text, uint8_t *key,
36
                                                      uint8_t *n1, uint32_t ctr);
37
extern void
38
Hacl_Chacha20Poly1305_128_aead_encrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
39
                                       uint8_t *aad, uint32_t mlen, uint8_t *m,
40
                                       uint8_t *cipher, uint8_t *mac);
41
extern uint32_t
42
Hacl_Chacha20Poly1305_128_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
43
                                       uint8_t *aad, uint32_t mlen, uint8_t *m,
44
                                       uint8_t *cipher, uint8_t *mac);
45
46
// Forward declaration from Hacl_Chacha20_Vec256.h and Hacl_Chacha20Poly1305_256.h.
47
extern void Hacl_Chacha20_Vec256_chacha20_encrypt_256(uint32_t len, uint8_t *out,
48
                                                      uint8_t *text, uint8_t *key,
49
                                                      uint8_t *n1, uint32_t ctr);
50
extern void
51
Hacl_Chacha20Poly1305_256_aead_encrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
52
                                       uint8_t *aad, uint32_t mlen, uint8_t *m,
53
                                       uint8_t *cipher, uint8_t *mac);
54
extern uint32_t
55
Hacl_Chacha20Poly1305_256_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
56
                                       uint8_t *aad, uint32_t mlen, uint8_t *m,
57
                                       uint8_t *cipher, uint8_t *mac);
58
59
// Forward declaration from Hacl_Chacha20.h and Hacl_Chacha20Poly1305_32.h.
60
extern void Hacl_Chacha20_chacha20_encrypt(uint32_t len, uint8_t *out,
61
                                           uint8_t *text, uint8_t *key,
62
                                           uint8_t *n1, uint32_t ctr);
63
extern void
64
Hacl_Chacha20Poly1305_32_aead_encrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
65
                                      uint8_t *aad, uint32_t mlen, uint8_t *m,
66
                                      uint8_t *cipher, uint8_t *mac);
67
extern uint32_t
68
Hacl_Chacha20Poly1305_32_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
69
                                      uint8_t *aad, uint32_t mlen, uint8_t *m,
70
                                      uint8_t *cipher, uint8_t *mac);
71
72
// Forward declaration from chacha20-ppc64le.S
73
void chacha20vsx(uint32_t len, uint8_t *output, uint8_t *block, uint8_t *k,
74
                 uint8_t *nonce, uint32_t ctr);
75
76
// Forward declaration from chacha20poly1305-ppc.c
77
extern void
78
Chacha20Poly1305_vsx_aead_encrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
79
                                  uint8_t *aad, uint32_t mlen, uint8_t *m,
80
                                  uint8_t *cipher, uint8_t *mac);
81
extern uint32_t
82
Chacha20Poly1305_vsx_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
83
                                  uint8_t *aad, uint32_t mlen, uint8_t *m,
84
                                  uint8_t *cipher, uint8_t *mac);
85
86
SECStatus
87
ChaCha20_InitContext(ChaCha20Context *ctx, const unsigned char *key,
88
                     unsigned int keyLen, const unsigned char *nonce,
89
                     unsigned int nonceLen, PRUint32 ctr)
90
0
{
91
#ifdef NSS_DISABLE_CHACHAPOLY
92
    return SECFailure;
93
#else
94
0
    if (keyLen != 32) {
95
0
        PORT_SetError(SEC_ERROR_BAD_KEY);
96
0
        return SECFailure;
97
0
    }
98
0
    if (nonceLen != 12) {
99
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
100
0
        return SECFailure;
101
0
    }
102
103
0
    ctx->counter = ctr;
104
0
    PORT_Memcpy(ctx->key, key, sizeof(ctx->key));
105
0
    PORT_Memcpy(ctx->nonce, nonce, sizeof(ctx->nonce));
106
107
0
    NSS_CLASSIFY(ctx->nonce, sizeof(ctx->nonce));
108
0
    NSS_CLASSIFY(ctx->key, sizeof(ctx->key));
109
110
0
    return SECSuccess;
111
0
#endif
112
0
}
113
114
ChaCha20Context *
115
ChaCha20_CreateContext(const unsigned char *key, unsigned int keyLen,
116
                       const unsigned char *nonce, unsigned int nonceLen,
117
                       PRUint32 ctr)
118
0
{
119
#ifdef NSS_DISABLE_CHACHAPOLY
120
    return NULL;
121
#else
122
0
    ChaCha20Context *ctx;
123
124
0
    ctx = PORT_New(ChaCha20Context);
125
0
    if (ctx == NULL) {
126
0
        return NULL;
127
0
    }
128
129
0
    if (ChaCha20_InitContext(ctx, key, keyLen, nonce, nonceLen, ctr) != SECSuccess) {
130
0
        PORT_Free(ctx);
131
0
        ctx = NULL;
132
0
    }
133
134
0
    return ctx;
135
0
#endif
136
0
}
137
138
void
139
ChaCha20_DestroyContext(ChaCha20Context *ctx, PRBool freeit)
140
0
{
141
0
#ifndef NSS_DISABLE_CHACHAPOLY
142
0
    PORT_Memset(ctx, 0, sizeof(*ctx));
143
0
    if (freeit) {
144
0
        PORT_Free(ctx);
145
0
    }
146
0
#endif
147
0
}
148
149
SECStatus
150
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
151
                             const unsigned char *key, unsigned int keyLen,
152
                             unsigned int tagLen)
153
164
{
154
#ifdef NSS_DISABLE_CHACHAPOLY
155
    return SECFailure;
156
#else
157
164
    if (keyLen != 32) {
158
1
        PORT_SetError(SEC_ERROR_BAD_KEY);
159
1
        return SECFailure;
160
1
    }
161
163
    if (tagLen != 16) {
162
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
163
0
        return SECFailure;
164
0
    }
165
166
163
    PORT_Memcpy(ctx->key, key, sizeof(ctx->key));
167
163
    ctx->tagLen = tagLen;
168
169
163
    NSS_CLASSIFY(ctx->key, sizeof(ctx->key));
170
171
163
    return SECSuccess;
172
163
#endif
173
163
}
174
175
ChaCha20Poly1305Context *
176
ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
177
                               unsigned int tagLen)
178
156
{
179
#ifdef NSS_DISABLE_CHACHAPOLY
180
    return NULL;
181
#else
182
156
    ChaCha20Poly1305Context *ctx;
183
184
156
    ctx = PORT_New(ChaCha20Poly1305Context);
185
156
    if (ctx == NULL) {
186
0
        return NULL;
187
0
    }
188
189
156
    if (ChaCha20Poly1305_InitContext(ctx, key, keyLen, tagLen) != SECSuccess) {
190
0
        PORT_Free(ctx);
191
0
        ctx = NULL;
192
0
    }
193
194
156
    return ctx;
195
156
#endif
196
156
}
197
198
void
199
ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
200
163
{
201
163
#ifndef NSS_DISABLE_CHACHAPOLY
202
163
    PORT_Memset(ctx, 0, sizeof(*ctx));
203
163
    if (freeit) {
204
156
        PORT_Free(ctx);
205
156
    }
206
163
#endif
207
163
}
208
209
#ifndef NSS_DISABLE_CHACHAPOLY
210
void
211
ChaCha20Xor(uint8_t *output, uint8_t *block, uint32_t len, uint8_t *k,
212
            uint8_t *nonce, uint32_t ctr)
213
0
{
214
0
#ifdef NSS_X64
215
0
#ifndef NSS_DISABLE_AVX2
216
0
    if (avx2_support()) {
217
0
        Hacl_Chacha20_Vec256_chacha20_encrypt_256(len, output, block, k, nonce, ctr);
218
0
        return;
219
0
    }
220
0
#endif
221
222
0
#ifndef NSS_DISABLE_SSE3
223
0
    if (ssse3_support() && sse4_1_support() && avx_support()) {
224
0
        Hacl_Chacha20_Vec128_chacha20_encrypt_128(len, output, block, k, nonce, ctr);
225
0
        return;
226
0
    }
227
0
#endif
228
229
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
230
    !defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
231
    if (ppc_crypto_support()) {
232
        chacha20vsx(len, output, block, k, nonce, ctr);
233
        return;
234
    }
235
#endif
236
0
    {
237
0
        Hacl_Chacha20_chacha20_encrypt(len, output, block, k, nonce, ctr);
238
0
        return;
239
0
    }
240
0
}
241
#endif /* NSS_DISABLE_CHACHAPOLY */
242
243
SECStatus
244
ChaCha20_Xor(unsigned char *output, const unsigned char *block, unsigned int len,
245
             const unsigned char *k, const unsigned char *nonce, PRUint32 ctr)
246
0
{
247
#ifdef NSS_DISABLE_CHACHAPOLY
248
    return SECFailure;
249
#else
250
    // ChaCha has a 64 octet block, with a 32-bit block counter.
251
0
    if (sizeof(len) > 4) {
252
0
        unsigned long long len_ull = len;
253
0
        if (len_ull >= (1ULL << (6 + 32))) {
254
0
            PORT_SetError(SEC_ERROR_INPUT_LEN);
255
0
            return SECFailure;
256
0
        }
257
0
    }
258
0
    ChaCha20Xor(output, (uint8_t *)block, len, (uint8_t *)k,
259
0
                (uint8_t *)nonce, ctr);
260
0
    return SECSuccess;
261
0
#endif
262
0
}
263
264
SECStatus
265
ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
266
                      unsigned int *outputLen, unsigned int maxOutputLen,
267
                      const unsigned char *input, unsigned int inputLen,
268
                      const unsigned char *nonce, unsigned int nonceLen,
269
                      const unsigned char *ad, unsigned int adLen)
270
0
{
271
#ifdef NSS_DISABLE_CHACHAPOLY
272
    return SECFailure;
273
#else
274
275
0
    if (nonceLen != 12) {
276
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
277
0
        return SECFailure;
278
0
    }
279
    // ChaCha has a 64 octet block, with a 32-bit block counter.
280
0
    if (sizeof(inputLen) > 4) {
281
0
        unsigned long long inputLen_ull = inputLen;
282
0
        if (inputLen_ull >= (1ULL << (6 + 32))) {
283
0
            PORT_SetError(SEC_ERROR_INPUT_LEN);
284
0
            return SECFailure;
285
0
        }
286
0
    }
287
0
    if (maxOutputLen < inputLen + ctx->tagLen) {
288
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
289
0
        return SECFailure;
290
0
    }
291
292
0
#ifdef NSS_X64
293
0
#ifndef NSS_DISABLE_AVX2
294
0
    if (avx2_support()) {
295
0
        Hacl_Chacha20Poly1305_256_aead_encrypt(
296
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
297
0
            (uint8_t *)input, output, output + inputLen);
298
0
        goto finish;
299
0
    }
300
0
#endif
301
302
0
#ifndef NSS_DISABLE_SSE3
303
0
    if (ssse3_support() && sse4_1_support() && avx_support()) {
304
0
        Hacl_Chacha20Poly1305_128_aead_encrypt(
305
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
306
0
            (uint8_t *)input, output, output + inputLen);
307
0
        goto finish;
308
0
    }
309
0
#endif
310
311
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
312
    !defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
313
    if (ppc_crypto_support()) {
314
        Chacha20Poly1305_vsx_aead_encrypt(
315
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
316
            (uint8_t *)input, output, output + inputLen);
317
        goto finish;
318
    }
319
#endif
320
0
    {
321
0
        Hacl_Chacha20Poly1305_32_aead_encrypt(
322
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
323
0
            (uint8_t *)input, output, output + inputLen);
324
0
        goto finish;
325
0
    }
326
327
0
finish:
328
0
    *outputLen = inputLen + ctx->tagLen;
329
0
    return SECSuccess;
330
0
#endif
331
0
}
332
333
SECStatus
334
ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
335
                      unsigned int *outputLen, unsigned int maxOutputLen,
336
                      const unsigned char *input, unsigned int inputLen,
337
                      const unsigned char *nonce, unsigned int nonceLen,
338
                      const unsigned char *ad, unsigned int adLen)
339
7
{
340
#ifdef NSS_DISABLE_CHACHAPOLY
341
    return SECFailure;
342
#else
343
7
    unsigned int ciphertextLen;
344
345
7
    if (nonceLen != 12) {
346
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
347
0
        return SECFailure;
348
0
    }
349
7
    if (inputLen < ctx->tagLen) {
350
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
351
0
        return SECFailure;
352
0
    }
353
7
    ciphertextLen = inputLen - ctx->tagLen;
354
7
    if (maxOutputLen < ciphertextLen) {
355
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
356
0
        return SECFailure;
357
0
    }
358
    // ChaCha has a 64 octet block, with a 32-bit block counter.
359
7
    if (inputLen >= (1ULL << (6 + 32)) + ctx->tagLen) {
360
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
361
0
        return SECFailure;
362
0
    }
363
364
7
    uint32_t res = 1;
365
7
#ifdef NSS_X64
366
7
#ifndef NSS_DISABLE_AVX2
367
7
    if (avx2_support()) {
368
7
        res = Hacl_Chacha20Poly1305_256_aead_decrypt(
369
7
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
370
7
            (uint8_t *)output, (uint8_t *)input, (uint8_t *)input + ciphertextLen);
371
7
        goto finish;
372
7
    }
373
0
#endif
374
375
0
#ifndef NSS_DISABLE_SSE3
376
0
    if (ssse3_support() && sse4_1_support() && avx_support()) {
377
0
        res = Hacl_Chacha20Poly1305_128_aead_decrypt(
378
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
379
0
            (uint8_t *)output, (uint8_t *)input, (uint8_t *)input + ciphertextLen);
380
0
        goto finish;
381
0
    }
382
0
#endif
383
384
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
385
    !defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
386
    if (ppc_crypto_support()) {
387
        res = Chacha20Poly1305_vsx_aead_decrypt(
388
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
389
            (uint8_t *)output, (uint8_t *)input, (uint8_t *)input + ciphertextLen);
390
        goto finish;
391
    }
392
#endif
393
0
    {
394
0
        res = Hacl_Chacha20Poly1305_32_aead_decrypt(
395
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
396
0
            (uint8_t *)output, (uint8_t *)input, (uint8_t *)input + ciphertextLen);
397
0
        goto finish;
398
0
    }
399
400
7
finish:
401
7
    if (res) {
402
7
        PORT_SetError(SEC_ERROR_BAD_DATA);
403
7
        return SECFailure;
404
7
    }
405
406
0
    *outputLen = ciphertextLen;
407
0
    return SECSuccess;
408
7
#endif
409
7
}
410
411
SECStatus
412
ChaCha20Poly1305_Encrypt(const ChaCha20Poly1305Context *ctx,
413
                         unsigned char *output, unsigned int *outputLen,
414
                         unsigned int maxOutputLen, const unsigned char *input,
415
                         unsigned int inputLen, const unsigned char *nonce,
416
                         unsigned int nonceLen, const unsigned char *ad,
417
                         unsigned int adLen, unsigned char *outTag)
418
0
{
419
#ifdef NSS_DISABLE_CHACHAPOLY
420
    return SECFailure;
421
#else
422
423
0
    if (nonceLen != 12) {
424
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
425
0
        return SECFailure;
426
0
    }
427
    // ChaCha has a 64 octet block, with a 32-bit block counter.
428
0
    if (sizeof(inputLen) > 4) {
429
0
        unsigned long long inputLen_ull = inputLen;
430
0
        if (inputLen_ull >= (1ULL << (6 + 32))) {
431
0
            PORT_SetError(SEC_ERROR_INPUT_LEN);
432
0
            return SECFailure;
433
0
        }
434
0
    }
435
0
    if (maxOutputLen < inputLen) {
436
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
437
0
        return SECFailure;
438
0
    }
439
440
0
#ifdef NSS_X64
441
0
#ifndef NSS_DISABLE_AVX2
442
0
    if (avx2_support()) {
443
0
        Hacl_Chacha20Poly1305_256_aead_encrypt(
444
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
445
0
            (uint8_t *)input, output, outTag);
446
0
        goto finish;
447
0
    }
448
0
#endif
449
450
0
#ifndef NSS_DISABLE_SSE3
451
0
    if (ssse3_support() && sse4_1_support() && avx_support()) {
452
0
        Hacl_Chacha20Poly1305_128_aead_encrypt(
453
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
454
0
            (uint8_t *)input, output, outTag);
455
0
        goto finish;
456
0
    }
457
0
#endif
458
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
459
    !defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
460
    if (ppc_crypto_support()) {
461
        Chacha20Poly1305_vsx_aead_encrypt(
462
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
463
            (uint8_t *)input, output, outTag);
464
        goto finish;
465
    }
466
#endif
467
0
    {
468
0
        Hacl_Chacha20Poly1305_32_aead_encrypt(
469
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, inputLen,
470
0
            (uint8_t *)input, output, outTag);
471
0
        goto finish;
472
0
    }
473
474
0
finish:
475
0
    *outputLen = inputLen;
476
0
    return SECSuccess;
477
0
#endif
478
0
}
479
480
SECStatus
481
ChaCha20Poly1305_Decrypt(const ChaCha20Poly1305Context *ctx,
482
                         unsigned char *output, unsigned int *outputLen,
483
                         unsigned int maxOutputLen, const unsigned char *input,
484
                         unsigned int inputLen, const unsigned char *nonce,
485
                         unsigned int nonceLen, const unsigned char *ad,
486
                         unsigned int adLen, /* const */ unsigned char *tagIn)
487
0
{
488
#ifdef NSS_DISABLE_CHACHAPOLY
489
    return SECFailure;
490
#else
491
0
    unsigned int ciphertextLen;
492
493
0
    if (nonceLen != 12) {
494
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
495
0
        return SECFailure;
496
0
    }
497
0
    ciphertextLen = inputLen;
498
0
    if (maxOutputLen < ciphertextLen) {
499
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
500
0
        return SECFailure;
501
0
    }
502
    // ChaCha has a 64 octet block, with a 32-bit block counter.
503
0
    if (sizeof(inputLen) > 4) {
504
0
        unsigned long long inputLen_ull = inputLen;
505
0
        if (inputLen_ull >= (1ULL << (6 + 32))) {
506
0
            PORT_SetError(SEC_ERROR_INPUT_LEN);
507
0
            return SECFailure;
508
0
        }
509
0
    }
510
511
0
    uint32_t res = 1;
512
0
#ifdef NSS_X64
513
0
#ifndef NSS_DISABLE_AVX2
514
0
    if (avx2_support()) {
515
0
        res = Hacl_Chacha20Poly1305_256_aead_decrypt(
516
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
517
0
            (uint8_t *)output, (uint8_t *)input, (uint8_t *)tagIn);
518
0
        goto finish;
519
0
    }
520
0
#endif
521
522
0
#ifndef NSS_DISABLE_SSE3
523
0
    if (ssse3_support() && sse4_1_support() && avx_support()) {
524
0
        res = Hacl_Chacha20Poly1305_128_aead_decrypt(
525
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
526
0
            (uint8_t *)output, (uint8_t *)input, (uint8_t *)tagIn);
527
0
        goto finish;
528
0
    }
529
0
#endif
530
531
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) && \
532
    !defined(NSS_DISABLE_ALTIVEC) && !defined(NSS_DISABLE_CRYPTO_VSX)
533
    if (ppc_crypto_support()) {
534
        res = Chacha20Poly1305_vsx_aead_decrypt(
535
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
536
            (uint8_t *)output, (uint8_t *)input, (uint8_t *)tagIn);
537
        goto finish;
538
    }
539
#endif
540
0
    {
541
0
        res = Hacl_Chacha20Poly1305_32_aead_decrypt(
542
0
            (uint8_t *)ctx->key, (uint8_t *)nonce, adLen, (uint8_t *)ad, ciphertextLen,
543
0
            (uint8_t *)output, (uint8_t *)input, (uint8_t *)tagIn);
544
0
        goto finish;
545
0
    }
546
547
0
finish:
548
0
    if (res) {
549
0
        PORT_SetError(SEC_ERROR_BAD_DATA);
550
0
        return SECFailure;
551
0
    }
552
553
0
    *outputLen = ciphertextLen;
554
0
    return SECSuccess;
555
0
#endif
556
0
}