Commit 983a0148 authored by aoeu's avatar aoeu

Bug 1613235 - Add POWER ChaCha20 stream cipher vector acceleration. r=bbeurdouche

Depends on D107220

Differential Revision: https://phabricator.services.mozilla.com/D107221

--HG--
extra : moz-landing-system : lando
parent fcf26d1d
......@@ -21,6 +21,7 @@
#include "secoid.h"
#include "nssutil.h"
#include "ecl-curve.h"
#include "chacha20poly1305.h"
#include "pkcs1_vectors.h"
......@@ -628,19 +629,20 @@ typedef enum {
bltestSEED_ECB, /* SEED algorithm */
bltestSEED_CBC, /* SEED algorithm */
#endif
bltestCHACHA20, /* ChaCha20 + Poly1305 */
bltestRSA, /* Public Key Ciphers */
bltestRSA_OAEP, /* . (Public Key Enc.) */
bltestRSA_PSS, /* . (Public Key Sig.) */
bltestECDSA, /* . (Public Key Sig.) */
bltestDSA, /* . (Public Key Sig.) */
bltestMD2, /* Hash algorithms */
bltestMD5, /* . */
bltestSHA1, /* . */
bltestSHA224, /* . */
bltestSHA256, /* . */
bltestSHA384, /* . */
bltestSHA512, /* . */
bltestCHACHA20_CTR, /* ChaCha20 block cipher */
bltestCHACHA20, /* ChaCha20 + Poly1305 */
bltestRSA, /* Public Key Ciphers */
bltestRSA_OAEP, /* . (Public Key Enc.) */
bltestRSA_PSS, /* . (Public Key Sig.) */
bltestECDSA, /* . (Public Key Sig.) */
bltestDSA, /* . (Public Key Sig.) */
bltestMD2, /* Hash algorithms */
bltestMD5, /* . */
bltestSHA1, /* . */
bltestSHA224, /* . */
bltestSHA256, /* . */
bltestSHA384, /* . */
bltestSHA512, /* . */
NUMMODES
} bltestCipherMode;
......@@ -670,6 +672,7 @@ static char *mode_strings[] =
"seed_ecb",
"seed_cbc",
#endif
"chacha20_ctr",
"chacha20_poly1305",
"rsa",
"rsa_oaep",
......@@ -801,11 +804,7 @@ PRBool
is_symmkeyCipher(bltestCipherMode mode)
{
/* change as needed! */
#ifndef NSS_DISABLE_DEPRECATED_SEED
if (mode >= bltestDES_ECB && mode <= bltestSEED_CBC)
#else
if (mode >= bltestDES_ECB && mode <= bltestCAMELLIA_CBC)
#endif
if (mode >= bltestDES_ECB && mode <= bltestCHACHA20_CTR)
return PR_TRUE;
return PR_FALSE;
}
......@@ -842,6 +841,7 @@ is_singleShotCipher(bltestCipherMode mode)
switch (mode) {
case bltestAES_GCM:
case bltestAES_CTS:
case bltestCHACHA20_CTR:
case bltestCHACHA20:
return PR_TRUE;
default:
......@@ -897,6 +897,7 @@ cipher_requires_IV(bltestCipherMode mode)
#ifndef NSS_DISABLE_DEPRECATED_SEED
case bltestSEED_CBC:
#endif
case bltestCHACHA20_CTR:
case bltestCHACHA20:
return PR_TRUE;
default:
......@@ -1150,6 +1151,22 @@ aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
input, inputLen);
}
SECStatus
chacha20_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
unsigned int maxOutputLen, const unsigned char *input,
unsigned int inputLen)
{
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
ChaCha20Context *ctx = cx;
*outputLen = inputLen;
return ChaCha20_Xor(output, input, inputLen, ctx->key, ctx->nonce,
ctx->counter);
}
SECStatus
chacha20_poly1305_Encrypt(void *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
......@@ -1655,6 +1672,24 @@ bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
}
#endif /* NSS_DISABLE_DEPRECATED_SEED */
SECStatus
bltest_chacha20_ctr_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
const PRUint32 counter = 1;
bltestSymmKeyParams *sk = &cipherInfo->params.sk;
cipherInfo->cx = ChaCha20_CreateContext(sk->key.buf.data, sk->key.buf.len,
sk->iv.buf.data, sk->iv.buf.len,
counter);
if (cipherInfo->cx == NULL){
PR_fprintf(PR_STDERR, "ChaCha20_CreateContext() returned NULL\n"
"key must be 32 bytes, iv must be 12 bytes\n");
return SECFailure;
}
cipherInfo->cipher.symmkeyCipher = chacha20_Encrypt;
return SECSuccess;
}
SECStatus
bltest_chacha20_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
......@@ -2316,6 +2351,11 @@ cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt)
return bltest_seed_init(cipherInfo, encrypt);
break;
#endif /* NSS_DISABLE_DEPRECATED_SEED */
case bltestCHACHA20_CTR:
outlen = cipherInfo->input.pBuf.len;
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
return bltest_chacha20_ctr_init(cipherInfo, encrypt);
break;
case bltestCHACHA20:
outlen = cipherInfo->input.pBuf.len + (encrypt ? 16 : 0);
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
......@@ -2620,6 +2660,9 @@ cipherFinish(bltestCipherInfo *cipherInfo)
SEED_DestroyContext((SEEDContext *)cipherInfo->cx, PR_TRUE);
break;
#endif /* NSS_DISABLE_DEPRECATED_SEED */
case bltestCHACHA20_CTR:
ChaCha20_DestroyContext((ChaCha20Context *)cipherInfo->cx, PR_TRUE);
break;
case bltestCHACHA20:
ChaCha20Poly1305_DestroyContext((ChaCha20Poly1305Context *)
cipherInfo->cx,
......@@ -2706,7 +2749,10 @@ getHighUnitBytes(PRInt64 res)
}
}
return PR_smprintf("%d%s", spl[i], marks[i]);
if (i==0)
return PR_smprintf("%d%s", spl[i], marks[i]);
else
return PR_smprintf("%d%s %d%s", spl[i], marks[i], spl[i-1], marks[i-1]);
}
static void
......
......@@ -1041,6 +1041,27 @@ Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
/******************************************/
/*
** ChaCha20 block cipher
*/
extern SECStatus ChaCha20_InitContext(ChaCha20Context *ctx,
const unsigned char *key,
unsigned int keyLen,
const unsigned char *nonce,
unsigned int nonceLen,
PRUint32 ctr);
extern ChaCha20Context *ChaCha20_CreateContext(const unsigned char *key,
unsigned int keyLen,
const unsigned char *nonce,
unsigned int nonceLen,
PRUint32 ctr);
extern void ChaCha20_DestroyContext(ChaCha20Context *ctx, PRBool freeit);
/******************************************/
/*
** ChaCha20+Poly1305 AEAD
......
......@@ -245,6 +245,7 @@ struct SHA256ContextStr;
struct SHA512ContextStr;
struct AESKeyWrapContextStr;
struct SEEDContextStr;
struct ChaCha20ContextStr;
struct ChaCha20Poly1305ContextStr;
struct Blake2bContextStr;
......@@ -265,6 +266,7 @@ typedef struct SHA512ContextStr SHA512Context;
typedef struct SHA512ContextStr SHA384Context;
typedef struct AESKeyWrapContextStr AESKeyWrapContext;
typedef struct SEEDContextStr SEEDContext;
typedef struct ChaCha20ContextStr ChaCha20Context;
typedef struct ChaCha20Poly1305ContextStr ChaCha20Poly1305Context;
typedef struct Blake2bContextStr BLAKE2BContext;
......
......@@ -83,6 +83,66 @@ Chacha20Poly1305_vsx_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
uint8_t *aad, uint32_t mlen, uint8_t *m,
uint8_t *cipher, uint8_t *mac);
SECStatus
ChaCha20_InitContext(ChaCha20Context *ctx, const unsigned char *key,
unsigned int keyLen, const unsigned char *nonce,
unsigned int nonceLen, PRUint32 ctr)
{
#ifdef NSS_DISABLE_CHACHAPOLY
return SECFailure;
#else
if (keyLen != 32) {
PORT_SetError(SEC_ERROR_BAD_KEY);
return SECFailure;
}
if (nonceLen != 12) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
ctx->counter = ctr;
PORT_Memcpy(ctx->key, key, sizeof(ctx->key));
PORT_Memcpy(ctx->nonce, nonce, sizeof(ctx->nonce));
return SECSuccess;
#endif
}
ChaCha20Context *
ChaCha20_CreateContext(const unsigned char *key, unsigned int keyLen,
const unsigned char *nonce, unsigned int nonceLen,
PRUint32 ctr)
{
#ifdef NSS_DISABLE_CHACHAPOLY
return NULL;
#else
ChaCha20Context *ctx;
ctx = PORT_New(ChaCha20Context);
if (ctx == NULL) {
return NULL;
}
if (ChaCha20_InitContext(ctx, key, keyLen, nonce, nonceLen, ctr) != SECSuccess) {
PORT_Free(ctx);
ctx = NULL;
}
return ctx;
#endif
}
void
ChaCha20_DestroyContext(ChaCha20Context *ctx, PRBool freeit)
{
#ifndef NSS_DISABLE_CHACHAPOLY
PORT_Memset(ctx, 0, sizeof(*ctx));
if (freeit) {
PORT_Free(ctx);
}
#endif
}
SECStatus
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
const unsigned char *key, unsigned int keyLen,
......
......@@ -12,4 +12,10 @@ struct ChaCha20Poly1305ContextStr {
unsigned char tagLen;
};
struct ChaCha20ContextStr {
unsigned char key[32];
unsigned char nonce[12];
PRUint32 counter;
};
#endif /* _CHACHA20_POLY1305_H_ */
......@@ -371,9 +371,14 @@ static const struct FREEBLVectorStr vector =
AESKeyWrap_DecryptKWP,
/* End of version 3.023 */
KEA_PrimeCheck
KEA_PrimeCheck,
/* End of version 3.024 */
ChaCha20_InitContext,
ChaCha20_CreateContext,
ChaCha20_DestroyContext
/* End of version 3.025 */
};
const FREEBLVector*
......
......@@ -2158,6 +2158,36 @@ ChaCha20_Xor(unsigned char *output, const unsigned char *block, unsigned int len
return (vector->p_ChaCha20_Xor)(output, block, len, k, nonce, ctr);
}
SECStatus
ChaCha20_InitContext(ChaCha20Context *ctx, const unsigned char *key,
unsigned int keyLen,
const unsigned char *nonce,
unsigned int nonceLen,
PRUint32 ctr)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_ChaCha20_InitContext)(ctx, key, keyLen, nonce, nonceLen, ctr);
}
ChaCha20Context *
ChaCha20_CreateContext(const unsigned char *key, unsigned int keyLen,
const unsigned char *nonce, unsigned int nonceLen,
PRUint32 ctr)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return NULL;
return (vector->p_ChaCha20_CreateContext)(key, keyLen, nonce, nonceLen, ctr);
}
void
ChaCha20_DestroyContext(ChaCha20Context *ctx, PRBool freeit)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return;
(vector->p_ChaCha20_DestroyContext)(ctx, freeit);
}
SECStatus
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
const unsigned char *key, unsigned int keyLen,
......
......@@ -10,7 +10,7 @@
#include "blapi.h"
#define FREEBL_VERSION 0x0324
#define FREEBL_VERSION 0x0325
struct FREEBLVectorStr {
......@@ -815,6 +815,23 @@ struct FREEBLVectorStr {
PRBool (*p_KEA_PrimeCheck)(SECItem *prime);
/* Version 3.024 came to here */
SECStatus (*p_ChaCha20_InitContext)(ChaCha20Context *ctx,
const unsigned char *key,
unsigned int keyLen,
const unsigned char *nonce,
unsigned int nonceLen,
PRUint32 ctr);
ChaCha20Context *(*p_ChaCha20_CreateContext)(const unsigned char *key,
unsigned int keyLen,
const unsigned char *nonce,
unsigned int nonceLen,
PRUint32 ctr);
void (*p_ChaCha20_DestroyContext)(ChaCha20Context *ctx, PRBool freeit);
/* Version 3.025 came to here */
/* Add new function pointers at the end of this struct and bump
* FREEBL_VERSION at the beginning of this file. */
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment