diff options
author | aoeu <aoeuh@yandex.ru> | 2021-03-10 10:42:34 +0000 |
---|---|---|
committer | aoeu <aoeuh@yandex.ru> | 2021-03-10 10:42:34 +0000 |
commit | 45c7b75d5d2d873b117b06c0a551666e7ccc46d2 (patch) | |
tree | 90e025e97782f8950620e28522d382e5b966ad5e | |
parent | e8041519cd159440a6b35ef94c8d03ec4fecc429 (diff) | |
download | nss-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.c | 84 | ||||
-rw-r--r-- | lib/freebl/blapi.h | 21 | ||||
-rw-r--r-- | lib/freebl/blapit.h | 2 | ||||
-rw-r--r-- | lib/freebl/chacha20poly1305.c | 60 | ||||
-rw-r--r-- | lib/freebl/chacha20poly1305.h | 6 | ||||
-rw-r--r-- | lib/freebl/ldvector.c | 7 | ||||
-rw-r--r-- | lib/freebl/loader.c | 30 | ||||
-rw-r--r-- | lib/freebl/loader.h | 19 |
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. */ }; |