summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraoeu <aoeuh@yandex.ru>2021-03-10 10:42:34 +0000
committeraoeu <aoeuh@yandex.ru>2021-03-10 10:42:34 +0000
commit45c7b75d5d2d873b117b06c0a551666e7ccc46d2 (patch)
tree90e025e97782f8950620e28522d382e5b966ad5e
parente8041519cd159440a6b35ef94c8d03ec4fecc429 (diff)
downloadnss-hg-45c7b75d5d2d873b117b06c0a551666e7ccc46d2.tar.gz
Bug 1613235 - Add POWER ChaCha20 stream cipher vector acceleration. r=bbeurdouche
Depends on D107220 Differential Revision: https://phabricator.services.mozilla.com/D107221
-rw-r--r--cmd/bltest/blapitest.c84
-rw-r--r--lib/freebl/blapi.h21
-rw-r--r--lib/freebl/blapit.h2
-rw-r--r--lib/freebl/chacha20poly1305.c60
-rw-r--r--lib/freebl/chacha20poly1305.h6
-rw-r--r--lib/freebl/ldvector.c7
-rw-r--r--lib/freebl/loader.c30
-rw-r--r--lib/freebl/loader.h19
8 files changed, 208 insertions, 21 deletions
diff --git a/cmd/bltest/blapitest.c b/cmd/bltest/blapitest.c
index 06654ef65..76b9494f0 100644
--- a/cmd/bltest/blapitest.c
+++ b/cmd/bltest/blapitest.c
@@ -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:
@@ -1151,6 +1152,22 @@ aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
}
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,
const unsigned char *input, unsigned int inputLen,
@@ -1656,6 +1673,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)
{
const unsigned int tagLen = 16;
@@ -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
diff --git a/lib/freebl/blapi.h b/lib/freebl/blapi.h
index 6f806884e..3d1ff7269 100644
--- a/lib/freebl/blapi.h
+++ b/lib/freebl/blapi.h
@@ -1043,6 +1043,27 @@ Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
/******************************************/
/*
+** 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
*/
diff --git a/lib/freebl/blapit.h b/lib/freebl/blapit.h
index 03cf96381..0054e17b8 100644
--- a/lib/freebl/blapit.h
+++ b/lib/freebl/blapit.h
@@ -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;
diff --git a/lib/freebl/chacha20poly1305.c b/lib/freebl/chacha20poly1305.c
index aa1a63fe4..746fdb7a2 100644
--- a/lib/freebl/chacha20poly1305.c
+++ b/lib/freebl/chacha20poly1305.c
@@ -84,6 +84,66 @@ Chacha20Poly1305_vsx_aead_decrypt(uint8_t *k, uint8_t *n1, uint32_t aadlen,
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,
unsigned int tagLen)
diff --git a/lib/freebl/chacha20poly1305.h b/lib/freebl/chacha20poly1305.h
index c77632aa1..fff528af3 100644
--- a/lib/freebl/chacha20poly1305.h
+++ b/lib/freebl/chacha20poly1305.h
@@ -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_ */
diff --git a/lib/freebl/ldvector.c b/lib/freebl/ldvector.c
index f14425f21..ac3b862b5 100644
--- a/lib/freebl/ldvector.c
+++ b/lib/freebl/ldvector.c
@@ -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*
diff --git a/lib/freebl/loader.c b/lib/freebl/loader.c
index 891516fa5..3c61471de 100644
--- a/lib/freebl/loader.c
+++ b/lib/freebl/loader.c
@@ -2159,6 +2159,36 @@ ChaCha20_Xor(unsigned char *output, const unsigned char *block, unsigned int len
}
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,
unsigned int tagLen)
diff --git a/lib/freebl/loader.h b/lib/freebl/loader.h
index 0b5ee5ef0..eb3046d27 100644
--- a/lib/freebl/loader.h
+++ b/lib/freebl/loader.h
@@ -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. */
};