mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-13 11:10:13 +01:00
Merge pull request #38 from roytam1/nss-vc71-fix
Nss vc71 fix and more updates
This commit is contained in:
commit
15b368a2fe
@ -26,7 +26,9 @@ include $(CORE_DEPTH)/coreconf/config.mk
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
|
||||
ifdef NSS_DISABLE_GTESTS
|
||||
DIRS := $(filter-out external_tests,$(DIRS))
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
@ -56,7 +58,11 @@ NSPR_CONFIGURE = $(CORE_DEPTH)/../nspr/configure
|
||||
#
|
||||
|
||||
ifeq ($(OS_TARGET),Android)
|
||||
NSPR_CONFIGURE_OPTS += --with-android-ndk=$(ANDROID_NDK) --target=arm-linux-androideabi --with-android-version=$(OS_TARGET_RELEASE)
|
||||
NSPR_CONFIGURE_OPTS += --with-android-ndk=$(ANDROID_NDK) \
|
||||
--target=$(ANDROID_PREFIX) \
|
||||
--with-android-version=$(OS_TARGET_RELEASE) \
|
||||
--with-android-toolchain=$(ANDROID_TOOLCHAIN) \
|
||||
--with-android-platform=$(ANDROID_SYSROOT)
|
||||
endif
|
||||
ifdef BUILD_OPT
|
||||
NSPR_CONFIGURE_OPTS += --disable-debug --enable-optimize
|
||||
|
@ -613,6 +613,17 @@ typedef SECStatus (* bltestSymmCipherFn)(void *cx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen);
|
||||
|
||||
typedef SECStatus (* bltestAEADFn)(void *cx,
|
||||
unsigned char *output,
|
||||
unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen,
|
||||
const unsigned char *nonce,
|
||||
unsigned int nonceLen,
|
||||
const unsigned char *ad,
|
||||
unsigned int adLen);
|
||||
|
||||
typedef SECStatus (* bltestPubKeyCipherFn)(void *key,
|
||||
SECItem *output,
|
||||
const SECItem *input);
|
||||
@ -646,6 +657,7 @@ typedef enum {
|
||||
bltestCAMELLIA_CBC, /* . */
|
||||
bltestSEED_ECB, /* SEED algorithm */
|
||||
bltestSEED_CBC, /* SEED algorithm */
|
||||
bltestCHACHA20, /* ChaCha20 + Poly1305 */
|
||||
bltestRSA, /* Public Key Ciphers */
|
||||
bltestRSA_OAEP, /* . (Public Key Enc.) */
|
||||
bltestRSA_PSS, /* . (Public Key Sig.) */
|
||||
@ -685,6 +697,7 @@ static char *mode_strings[] =
|
||||
"camellia_cbc",
|
||||
"seed_ecb",
|
||||
"seed_cbc",
|
||||
"chacha20_poly1305",
|
||||
"rsa",
|
||||
"rsa_oaep",
|
||||
"rsa_pss",
|
||||
@ -805,6 +818,7 @@ struct bltestCipherInfoStr {
|
||||
/* Cipher function (encrypt/decrypt/sign/verify/hash) */
|
||||
union {
|
||||
bltestSymmCipherFn symmkeyCipher;
|
||||
bltestAEADFn aeadCipher;
|
||||
bltestPubKeyCipherFn pubkeyCipher;
|
||||
bltestHashCipherFn hashCipher;
|
||||
} cipher;
|
||||
@ -826,13 +840,29 @@ is_symmkeyCipher(bltestCipherMode mode)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
is_aeadCipher(bltestCipherMode mode)
|
||||
{
|
||||
/* change as needed! */
|
||||
switch (mode) {
|
||||
case bltestCHACHA20:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
is_authCipher(bltestCipherMode mode)
|
||||
{
|
||||
/* change as needed! */
|
||||
if (mode == bltestAES_GCM)
|
||||
return PR_TRUE;
|
||||
return PR_FALSE;
|
||||
switch (mode) {
|
||||
case bltestAES_GCM:
|
||||
case bltestCHACHA20:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -840,11 +870,14 @@ PRBool
|
||||
is_singleShotCipher(bltestCipherMode mode)
|
||||
{
|
||||
/* change as needed! */
|
||||
if (mode == bltestAES_GCM)
|
||||
return PR_TRUE;
|
||||
if (mode == bltestAES_CTS)
|
||||
return PR_TRUE;
|
||||
return PR_FALSE;
|
||||
switch (mode) {
|
||||
case bltestAES_GCM:
|
||||
case bltestAES_CTS:
|
||||
case bltestCHACHA20:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -878,16 +911,24 @@ PRBool
|
||||
cipher_requires_IV(bltestCipherMode mode)
|
||||
{
|
||||
/* change as needed! */
|
||||
if (mode == bltestDES_CBC || mode == bltestDES_EDE_CBC ||
|
||||
mode == bltestRC2_CBC ||
|
||||
switch (mode) {
|
||||
case bltestDES_CBC:
|
||||
case bltestDES_EDE_CBC:
|
||||
case bltestRC2_CBC:
|
||||
#ifdef NSS_SOFTOKEN_DOES_RC5
|
||||
mode == bltestRC5_CBC ||
|
||||
case bltestRC5_CBC:
|
||||
#endif
|
||||
mode == bltestAES_CBC || mode == bltestAES_CTS ||
|
||||
mode == bltestAES_CTR || mode == bltestAES_GCM ||
|
||||
mode == bltestCAMELLIA_CBC || mode == bltestSEED_CBC)
|
||||
return PR_TRUE;
|
||||
return PR_FALSE;
|
||||
case bltestAES_CBC:
|
||||
case bltestAES_CTS:
|
||||
case bltestAES_CTR:
|
||||
case bltestAES_GCM:
|
||||
case bltestCAMELLIA_CBC:
|
||||
case bltestSEED_CBC:
|
||||
case bltestCHACHA20:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus finishIO(bltestIO *output, PRFileDesc *file);
|
||||
@ -1126,6 +1167,30 @@ aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
|
||||
input, inputLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
chacha20_poly1305_Encrypt(void *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
return ChaCha20Poly1305_Seal((ChaCha20Poly1305Context *)cx, output,
|
||||
outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
chacha20_poly1305_Decrypt(void *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
return ChaCha20Poly1305_Open((ChaCha20Poly1305Context *)cx, output,
|
||||
outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
camellia_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen, const unsigned char *input,
|
||||
@ -1575,6 +1640,21 @@ bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
bltest_chacha20_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
|
||||
{
|
||||
const unsigned int tagLen = 16;
|
||||
const bltestSymmKeyParams *sk = &cipherInfo->params.sk;
|
||||
cipherInfo->cx = ChaCha20Poly1305_CreateContext(sk->key.buf.data,
|
||||
sk->key.buf.len, tagLen);
|
||||
|
||||
if (encrypt)
|
||||
cipherInfo->cipher.aeadCipher = chacha20_poly1305_Encrypt;
|
||||
else
|
||||
cipherInfo->cipher.aeadCipher = chacha20_poly1305_Decrypt;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
|
||||
{
|
||||
@ -2226,6 +2306,11 @@ cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt)
|
||||
cipherInfo->input.pBuf.len);
|
||||
return bltest_seed_init(cipherInfo, encrypt);
|
||||
break;
|
||||
case bltestCHACHA20:
|
||||
outlen = cipherInfo->input.pBuf.len + (encrypt ? 16 : 0);
|
||||
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
|
||||
return bltest_chacha20_init(cipherInfo, encrypt);
|
||||
break;
|
||||
case bltestRSA:
|
||||
case bltestRSA_OAEP:
|
||||
case bltestRSA_PSS:
|
||||
@ -2376,6 +2461,55 @@ cipherDoOp(bltestCipherInfo *cipherInfo)
|
||||
}
|
||||
}
|
||||
TIMEFINISH(cipherInfo->optime, 1.0);
|
||||
} else if (is_aeadCipher(cipherInfo->mode)) {
|
||||
const unsigned char *input = cipherInfo->input.pBuf.data;
|
||||
unsigned int inputLen = cipherInfo->input.pBuf.len;
|
||||
unsigned char *output = cipherInfo->output.pBuf.data;
|
||||
unsigned int outputLen;
|
||||
bltestSymmKeyParams *sk = &cipherInfo->params.sk;
|
||||
bltestAuthSymmKeyParams *ask = &cipherInfo->params.ask;
|
||||
|
||||
TIMESTART();
|
||||
rv = (*cipherInfo->cipher.aeadCipher)(
|
||||
cipherInfo->cx,
|
||||
output, &outputLen, maxLen,
|
||||
input, inputLen,
|
||||
sk->iv.buf.data, sk->iv.buf.len,
|
||||
ask->aad.buf.data, ask->aad.buf.len);
|
||||
CHECKERROR(rv, __LINE__);
|
||||
cipherInfo->output.pBuf.len = outputLen;
|
||||
TIMEFINISH(cipherInfo->optime, 1.0);
|
||||
|
||||
cipherInfo->repetitions = 0;
|
||||
if (cipherInfo->repetitionsToPerfom != 0) {
|
||||
TIMESTART();
|
||||
for (i=0; i<cipherInfo->repetitionsToPerfom; i++,
|
||||
cipherInfo->repetitions++) {
|
||||
rv = (*cipherInfo->cipher.aeadCipher)(
|
||||
cipherInfo->cx,
|
||||
output, &outputLen, maxLen,
|
||||
input, inputLen,
|
||||
sk->iv.buf.data, sk->iv.buf.len,
|
||||
ask->aad.buf.data, ask->aad.buf.len);
|
||||
CHECKERROR(rv, __LINE__);
|
||||
}
|
||||
} else {
|
||||
int opsBetweenChecks = 0;
|
||||
TIMEMARK(cipherInfo->seconds);
|
||||
while (! (TIMETOFINISH())) {
|
||||
int j = 0;
|
||||
for (;j < opsBetweenChecks;j++) {
|
||||
(*cipherInfo->cipher.aeadCipher)(
|
||||
cipherInfo->cx,
|
||||
output, &outputLen, maxLen,
|
||||
input, inputLen,
|
||||
sk->iv.buf.data, sk->iv.buf.len,
|
||||
ask->aad.buf.data, ask->aad.buf.len);
|
||||
}
|
||||
cipherInfo->repetitions += j;
|
||||
}
|
||||
}
|
||||
TIMEFINISH(cipherInfo->optime, 1.0);
|
||||
} else if (is_pubkeyCipher(cipherInfo->mode)) {
|
||||
TIMESTART();
|
||||
rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
|
||||
@ -2477,6 +2611,10 @@ cipherFinish(bltestCipherInfo *cipherInfo)
|
||||
case bltestSEED_CBC:
|
||||
SEED_DestroyContext((SEEDContext *)cipherInfo->cx, PR_TRUE);
|
||||
break;
|
||||
case bltestCHACHA20:
|
||||
ChaCha20Poly1305_DestroyContext((ChaCha20Poly1305Context *)
|
||||
cipherInfo->cx, PR_TRUE);
|
||||
break;
|
||||
case bltestRC2_ECB:
|
||||
case bltestRC2_CBC:
|
||||
RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE);
|
||||
@ -2808,6 +2946,7 @@ get_params(PLArenaPool *arena, bltestParams *params,
|
||||
#endif
|
||||
switch (mode) {
|
||||
case bltestAES_GCM:
|
||||
case bltestCHACHA20:
|
||||
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "aad", j);
|
||||
load_file_data(arena, ¶ms->ask.aad, filename, bltestBinary);
|
||||
case bltestDES_CBC:
|
||||
@ -3552,7 +3691,7 @@ int main(int argc, char **argv)
|
||||
unsigned int keySize = 1024;
|
||||
unsigned long exponent = 65537;
|
||||
int rounds = 1;
|
||||
int ret;
|
||||
int ret = -1;
|
||||
|
||||
if (bltest.options[opt_KeySize].activated) {
|
||||
keySize = PORT_Atoi(bltest.options[opt_KeySize].arg);
|
||||
@ -3753,7 +3892,8 @@ print_usage:
|
||||
/* Set up an encryption key. */
|
||||
keysize = 0;
|
||||
file = NULL;
|
||||
if (is_symmkeyCipher(cipherInfo->mode)) {
|
||||
if (is_symmkeyCipher(cipherInfo->mode) ||
|
||||
is_aeadCipher(cipherInfo->mode)) {
|
||||
char *keystr = NULL; /* if key is on command line */
|
||||
if (bltest.options[opt_Key].activated) {
|
||||
if (bltest.options[opt_CmdLine].activated) {
|
||||
|
1
security/nss/cmd/bltest/tests/chacha20_poly1305/aad0
Normal file
1
security/nss/cmd/bltest/tests/chacha20_poly1305/aad0
Normal file
@ -0,0 +1 @@
|
||||
PQRSタチツテトナニヌ
|
@ -0,0 +1 @@
|
||||
0xqNNGSOYNt7hq+8U+9+wqSt7VEpbgj+qeK1pzbuYtY9vqRejKlnEoL6+2naknKLGnHeCp4GCykF1qW2fs07NpLdvX8td4uMmAOu4ygJG1j6syTk+tZ1lFWFgItIMde8P/Te8I5Lep3ldtJlhs7GS2EWGuELWU8J4mp+kC7L0GAGkQ==
|
@ -0,0 +1 @@
|
||||
ZKCGFXWGGvRg8GLHm+ZDvV6AXP00XPOJ8QhnCsdsjLJMbPwYdV1D7qCe6U44LSawvbe3PDIbAQDU8Dt/NViUzzMvgw5xC5fOmMioSr0LlIEUrRduAI0zvWD5grH/N8hVl5egbvTw72HBhjJOKzUGODYGkHtqfAKw+fYVe1PIZ+S5Fmx2e4BNRqWbUhbN56TpkEDFpAQzIl7igqGwoGxSPq9FNNf4P6EVWwBHcYy8VGoNBysEs1ZO6htCInP1SCcaC7IxYFP6dpkZVevWMVlDTs67TkZtrloQc6ZydicJehBJ5hfZHTYQlPpo8P93mHEwMFvqui7aBN+Ze3FNbG8sKaatXLQCKwJwm+6tnWeJDLsiOSM2/qGFHzg=
|
1
security/nss/cmd/bltest/tests/chacha20_poly1305/key0
Normal file
1
security/nss/cmd/bltest/tests/chacha20_poly1305/key0
Normal file
@ -0,0 +1 @@
|
||||
≠ヤ<EFBFBD>㊧炎旧克署葬灯楓利劒屆撼<EFBFBD>
|
1
security/nss/cmd/bltest/tests/chacha20_poly1305/key1
Normal file
1
security/nss/cmd/bltest/tests/chacha20_poly1305/key1
Normal file
@ -0,0 +1 @@
|
||||
<1C>@<40><>Uӊ<55>3<EFBFBD><33><04><><EFBFBD>G9<17>@+<2B> <09><>\<5C> pu<70>
|
1
security/nss/cmd/bltest/tests/chacha20_poly1305/numtests
Normal file
1
security/nss/cmd/bltest/tests/chacha20_poly1305/numtests
Normal file
@ -0,0 +1 @@
|
||||
2
|
@ -0,0 +1 @@
|
||||
Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.
|
@ -0,0 +1 @@
|
||||
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as /“work in progress./”
|
@ -508,8 +508,8 @@ get_serial_number(Pair *data)
|
||||
if (find_field_bool(data, "serial-auto", PR_TRUE)) {
|
||||
serialFile = fopen(filename, "r");
|
||||
if (serialFile != NULL) {
|
||||
fread(&serial, sizeof(int), 1, serialFile);
|
||||
if (ferror(serialFile) != 0) {
|
||||
size_t nread = fread(&serial, sizeof(int), 1, serialFile);
|
||||
if (ferror(serialFile) != 0 || nread != 1) {
|
||||
error_out("Error: Unable to read serial number file");
|
||||
}
|
||||
if (serial == -1) {
|
||||
|
@ -970,6 +970,7 @@ AddNameConstraints(void *extHandle)
|
||||
|
||||
if (!arena || ! constraints) {
|
||||
SECU_PrintError(progName, "out of memory");
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -74,7 +74,9 @@ char *SEC_GetPassword(FILE *input, FILE *output, char *prompt,
|
||||
echoOff(infd);
|
||||
}
|
||||
|
||||
QUIET_FGETS ( phrase, sizeof(phrase), input);
|
||||
if (QUIET_FGETS(phrase, sizeof(phrase), input) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (isTTY) {
|
||||
fprintf(output, "\n");
|
||||
@ -87,7 +89,7 @@ char *SEC_GetPassword(FILE *input, FILE *output, char *prompt,
|
||||
/* Validate password */
|
||||
if (!(*ok)(phrase)) {
|
||||
/* Not weird enough */
|
||||
if (!isTTY) return 0;
|
||||
if (!isTTY) return NULL;
|
||||
fprintf(output, "Password must be at least 8 characters long with one or more\n");
|
||||
fprintf(output, "non-alphabetic characters\n");
|
||||
continue;
|
||||
|
@ -471,6 +471,9 @@ loser:
|
||||
PR_Free(_this->arch);
|
||||
_this->arch = NULL;
|
||||
}
|
||||
if(copy) {
|
||||
PR_Free(copy);
|
||||
}
|
||||
|
||||
return errStr;
|
||||
}
|
||||
@ -1467,7 +1470,6 @@ Pk11Install_Pair_delete(Pk11Install_Pair* _this)
|
||||
{
|
||||
PR_Free(_this->key);
|
||||
Pk11Install_ValueList_delete(_this->list);
|
||||
PR_Free(_this->list);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
@ -833,7 +833,10 @@ rm_dash_r (char *path)
|
||||
/* Recursively delete all entries in the directory */
|
||||
while((entry = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
|
||||
sprintf(filename, "%s/%s", path, entry->name);
|
||||
if(rm_dash_r(filename)) return -1;
|
||||
if(rm_dash_r(filename)) {
|
||||
PR_CloseDir(dir);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(PR_CloseDir(dir) != PR_SUCCESS) {
|
||||
|
@ -712,6 +712,8 @@ ChangePW(char *tokenName, char *pwFile, char *newpwFile)
|
||||
newpw2 = SECU_GetPasswordString(NULL, "Re-enter new password: ");
|
||||
if(strcmp(newpw, newpw2)) {
|
||||
PR_fprintf(PR_STDOUT, msgStrings[PW_MATCH_MSG]);
|
||||
PORT_ZFree(newpw, strlen(newpw));
|
||||
PORT_ZFree(newpw2, strlen(newpw2));
|
||||
} else {
|
||||
matching = PR_TRUE;
|
||||
}
|
||||
@ -738,16 +740,13 @@ ChangePW(char *tokenName, char *pwFile, char *newpwFile)
|
||||
|
||||
loser:
|
||||
if(oldpw) {
|
||||
memset(oldpw, 0, strlen(oldpw));
|
||||
PORT_Free(oldpw);
|
||||
PORT_ZFree(oldpw, strlen(oldpw));
|
||||
}
|
||||
if(newpw) {
|
||||
memset(newpw, 0, strlen(newpw));
|
||||
PORT_Free(newpw);
|
||||
PORT_ZFree(newpw, strlen(newpw));
|
||||
}
|
||||
if(newpw2) {
|
||||
memset(newpw2, 0, strlen(newpw2));
|
||||
PORT_Free(newpw2);
|
||||
PORT_ZFree(newpw2, strlen(newpw2));
|
||||
}
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
|
@ -2090,8 +2090,8 @@ CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
|
||||
}
|
||||
PKM_LogIt("C_GetMechanismList returned the mechanism types:\n");
|
||||
if (verbose) {
|
||||
for (i = 1; i <= mechanismCount; i++) {
|
||||
mechName = getName(pMechanismList[(i-1)], ConstMechanism);
|
||||
for (i = 0; i < mechanismCount; i++) {
|
||||
mechName = getName(pMechanismList[(i)], ConstMechanism);
|
||||
|
||||
/* output two mechanism name on each line */
|
||||
/* currently the longest known mechansim name length is 37 */
|
||||
@ -2100,7 +2100,7 @@ CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
|
||||
} else {
|
||||
printf("Unknown mechanism: 0x%08lX ", pMechanismList[i]);
|
||||
}
|
||||
if ((i != 0) && ((i % 2) == 0 )) printf("\n");
|
||||
if ((i % 2) == 1 ) printf("\n");
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" };
|
||||
#define MAX_BULK_TEST 1048576 /* 1 MB */
|
||||
static PRBool testBulk;
|
||||
static PRUint32 testBulkSize = DEFAULT_BULK_TEST;
|
||||
static PRUint32 testBulkTotal;
|
||||
static PRInt32 testBulkTotal;
|
||||
static char* testBulkBuf;
|
||||
static PRDescIdentity log_layer_id = PR_INVALID_IO_LAYER;
|
||||
static PRFileDesc *loggingFD;
|
||||
@ -74,10 +74,10 @@ static PRIOMethods loggingMethods;
|
||||
static PRBool logStats;
|
||||
static PRBool loggingLayer;
|
||||
static int logPeriod = 30;
|
||||
static PRUint32 loggerOps;
|
||||
static PRUint32 loggerBytes;
|
||||
static PRUint32 loggerBytesTCP;
|
||||
static PRUint32 bulkSentChunks;
|
||||
static PRInt32 loggerOps;
|
||||
static PRInt32 loggerBytes;
|
||||
static PRInt32 loggerBytesTCP;
|
||||
static PRInt32 bulkSentChunks;
|
||||
static enum ocspStaplingModeEnum {
|
||||
osm_disabled, /* server doesn't support stapling */
|
||||
osm_good, /* supply a signed good status */
|
||||
@ -428,10 +428,11 @@ printSecurityInfo(PRFileDesc *fd)
|
||||
suite.macBits, suite.macAlgorithmName);
|
||||
FPRINTF(stderr,
|
||||
"selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
|
||||
" Compression: %s\n",
|
||||
" Compression: %s, Extended Master Secret: %s\n",
|
||||
channel.authKeyBits, suite.authAlgorithmName,
|
||||
channel.keaKeyBits, suite.keaTypeName,
|
||||
channel.compressionMethodName);
|
||||
channel.compressionMethodName,
|
||||
channel.extendedMasterSecretUsed ? "Yes": "No");
|
||||
}
|
||||
}
|
||||
if (verbose) {
|
||||
@ -751,8 +752,8 @@ logger(void *arg)
|
||||
PRIntervalTime period;
|
||||
PRIntervalTime previousTime;
|
||||
PRIntervalTime latestTime;
|
||||
PRUint32 previousOps;
|
||||
PRUint32 ops;
|
||||
PRInt32 previousOps;
|
||||
PRInt32 ops;
|
||||
PRIntervalTime logPeriodTicks = PR_TicksPerSecond();
|
||||
PRFloat64 secondsPerTick = 1.0 / (PRFloat64)logPeriodTicks;
|
||||
int iterations = 0;
|
||||
@ -771,7 +772,7 @@ logger(void *arg)
|
||||
*/
|
||||
PR_Sleep(logPeriodTicks);
|
||||
secondsElapsed++;
|
||||
totalPeriodBytes += PR_ATOMIC_SET(&loggerBytes, 0);
|
||||
totalPeriodBytes += PR_ATOMIC_SET(&loggerBytes, 0);
|
||||
totalPeriodBytesTCP += PR_ATOMIC_SET(&loggerBytesTCP, 0);
|
||||
if (secondsElapsed != logPeriod) {
|
||||
continue;
|
||||
@ -837,6 +838,8 @@ PRBool testbypass = PR_FALSE;
|
||||
PRBool enableSessionTickets = PR_FALSE;
|
||||
PRBool enableCompression = PR_FALSE;
|
||||
PRBool failedToNegotiateName = PR_FALSE;
|
||||
PRBool enableExtendedMasterSecret = PR_FALSE;
|
||||
|
||||
static char *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX];
|
||||
static int virtServerNameIndex = 1;
|
||||
|
||||
@ -1942,6 +1945,13 @@ server_main(
|
||||
}
|
||||
}
|
||||
|
||||
if (enableExtendedMasterSecret) {
|
||||
rv = SSL_OptionSet(model_sock, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
errExit("error enabling extended master secret ");
|
||||
}
|
||||
}
|
||||
|
||||
for (kea = kt_rsa; kea < kt_kea_size; kea++) {
|
||||
if (cert[kea] != NULL) {
|
||||
secStatus = SSL_ConfigSecureServer(model_sock,
|
||||
@ -2218,7 +2228,7 @@ main(int argc, char **argv)
|
||||
** numbers, then capital letters, then lower case, alphabetical.
|
||||
*/
|
||||
optstate = PL_CreateOptState(argc, argv,
|
||||
"2:A:BC:DEH:L:M:NP:RS:T:U:V:W:Ya:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz");
|
||||
"2:A:BC:DEGH:L:M:NP:RS:T:U:V:W:Ya:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz");
|
||||
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
++optionsFound;
|
||||
switch(optstate->option) {
|
||||
@ -2234,6 +2244,8 @@ main(int argc, char **argv)
|
||||
case 'E': disableStepDown = PR_TRUE; break;
|
||||
case 'H': configureDHE = (PORT_Atoi(optstate->value) != 0); break;
|
||||
|
||||
case 'G': enableExtendedMasterSecret = PR_TRUE; break;
|
||||
|
||||
case 'I': /* reserved for OCSP multi-stapling */ break;
|
||||
|
||||
case 'L':
|
||||
|
@ -522,7 +522,7 @@ CK_RVtoStr(CK_RV errNum) {
|
||||
|
||||
/* Do binary search of table. */
|
||||
while (low + 1 < high) {
|
||||
i = (low + high) / 2;
|
||||
i = low + (high - low) / 2;
|
||||
num = errStrings[i].errNum;
|
||||
if (errNum == num)
|
||||
return errStrings[i].errString;
|
||||
|
@ -73,6 +73,9 @@ GenerateCert(char *nickname, int keysize, char *token)
|
||||
LL_L2UI(serial, PR_Now());
|
||||
|
||||
subject = GetSubjectFromUser(serial);
|
||||
if (!subject) {
|
||||
FatalError("Unable to get subject from user");
|
||||
}
|
||||
|
||||
cert = GenerateSelfSignedObjectSigningCert(nickname, db, subject,
|
||||
serial, keysize, token);
|
||||
@ -122,7 +125,9 @@ GetSubjectFromUser(unsigned long serial)
|
||||
#else
|
||||
PR_fprintf(PR_STDOUT, "certificate common name: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp == '\0') {
|
||||
sprintf(common_name_buf, "%s (%lu)", DEFAULT_COMMON_NAME,
|
||||
@ -144,7 +149,9 @@ GetSubjectFromUser(unsigned long serial)
|
||||
#else
|
||||
PR_fprintf(PR_STDOUT, "organization: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
org = PORT_ZAlloc(strlen(cp) + 5);
|
||||
@ -163,7 +170,9 @@ GetSubjectFromUser(unsigned long serial)
|
||||
#else
|
||||
PR_fprintf(PR_STDOUT, "organization unit: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
orgunit = PORT_ZAlloc(strlen(cp) + 6);
|
||||
@ -181,7 +190,9 @@ GetSubjectFromUser(unsigned long serial)
|
||||
#else
|
||||
PR_fprintf(PR_STDOUT, "state or province: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
state = PORT_ZAlloc(strlen(cp) + 6);
|
||||
@ -199,7 +210,9 @@ GetSubjectFromUser(unsigned long serial)
|
||||
#else
|
||||
PR_fprintf(PR_STDOUT, "country (must be exactly 2 characters): ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(cp);
|
||||
if (strlen(cp) != 2) {
|
||||
*cp = '\0'; /* country code must be 2 chars */
|
||||
@ -220,7 +233,9 @@ GetSubjectFromUser(unsigned long serial)
|
||||
#else
|
||||
PR_fprintf(PR_STDOUT, "username: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
uid = PORT_ZAlloc(strlen(cp) + 7);
|
||||
@ -238,7 +253,9 @@ GetSubjectFromUser(unsigned long serial)
|
||||
#else
|
||||
PR_fprintf(PR_STDOUT, "email address: ");
|
||||
#endif
|
||||
fgets(buf, STDIN_BUF_SIZE, stdin);
|
||||
if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
|
||||
return NULL;
|
||||
}
|
||||
cp = chop(buf);
|
||||
if (*cp != '\0') {
|
||||
email = PORT_ZAlloc(strlen(cp) + 5);
|
||||
|
@ -443,6 +443,10 @@ const char * V2CipherString(int cs_int)
|
||||
case 0x00C02C: cs_str = "TLS/ECDHE-ECDSA/AES256-GCM/SHA384"; break;
|
||||
case 0x00C02F: cs_str = "TLS/ECDHE-RSA/AES128-GCM/SHA256"; break;
|
||||
|
||||
case 0x00CCA8: cs_str = "TLS/ECDHE-RSA/CHACHA20-POLY1305/SHA256"; break;
|
||||
case 0x00CCA9: cs_str = "TLS/ECDHE-ECDSA/CHACHA20-POLY1305/SHA256"; break;
|
||||
case 0x00CCAA: cs_str = "TLS/DHE-RSA/CHACHA20-POLY1305/SHA256"; break;
|
||||
|
||||
case 0x00FEFF: cs_str = "SSL3/RSA-FIPS/3DESEDE-CBC/SHA"; break;
|
||||
case 0x00FEFE: cs_str = "SSL3/RSA-FIPS/DES-CBC/SHA"; break;
|
||||
case 0x00FFE1: cs_str = "SSL3/RSA-FIPS/DES56-CBC/SHA"; break;
|
||||
|
@ -129,10 +129,11 @@ void printSecurityInfo(PRFileDesc *fd)
|
||||
suite.macBits, suite.macAlgorithmName);
|
||||
FPRINTF(stderr,
|
||||
"tstclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
|
||||
" Compression: %s\n",
|
||||
" Compression: %s, Extended Master Secret: %s\n",
|
||||
channel.authKeyBits, suite.authAlgorithmName,
|
||||
channel.keaKeyBits, suite.keaTypeName,
|
||||
channel.compressionMethodName);
|
||||
channel.compressionMethodName,
|
||||
channel.extendedMasterSecretUsed ? "Yes": "No");
|
||||
}
|
||||
}
|
||||
cert = SSL_RevealCert(fd);
|
||||
@ -231,6 +232,7 @@ static void PrintParameterUsage(void)
|
||||
fprintf(stderr, "%-20s Enable compression.\n", "-z");
|
||||
fprintf(stderr, "%-20s Enable false start.\n", "-g");
|
||||
fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T");
|
||||
fprintf(stderr, "%-20s Enable the extended master secret extension (session hash).\n", "-G");
|
||||
fprintf(stderr, "%-20s Require fresh revocation info from side channel.\n"
|
||||
"%-20s -F once means: require for server cert only\n"
|
||||
"%-20s -F twice means: require for intermediates, too\n"
|
||||
@ -919,6 +921,7 @@ int main(int argc, char **argv)
|
||||
int enableFalseStart = 0;
|
||||
int enableCertStatus = 0;
|
||||
int forceFallbackSCSV = 0;
|
||||
int enableExtendedMasterSecret = 0;
|
||||
PRSocketOptionData opt;
|
||||
PRNetAddr addr;
|
||||
PRPollDesc pollset[2];
|
||||
@ -967,7 +970,7 @@ int main(int argc, char **argv)
|
||||
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
|
||||
|
||||
optstate = PL_CreateOptState(argc, argv,
|
||||
"46BCDFKM:OR:STV:W:Ya:bc:d:fgh:m:n:op:qr:st:uvw:xz");
|
||||
"46BCDFGKM:OR:STV:W:Ya:bc:d:fgh:m:n:op:qr:st:uvw:xz");
|
||||
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
switch (optstate->option) {
|
||||
case '?':
|
||||
@ -989,6 +992,8 @@ int main(int argc, char **argv)
|
||||
serverCertAuth.testFreshStatusFromSideChannel = PR_TRUE;
|
||||
break;
|
||||
|
||||
case 'G': enableExtendedMasterSecret = PR_TRUE; break;
|
||||
|
||||
case 'I': /* reserved for OCSP multi-stapling */ break;
|
||||
|
||||
case 'O': serverCertAuth.shouldPause = PR_FALSE; break;
|
||||
@ -1386,6 +1391,15 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* enable extended master secret mode */
|
||||
if (enableExtendedMasterSecret) {
|
||||
rv = SSL_OptionSet(s, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "error enabling extended master secret");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
SSL_SetPKCS11PinArg(s, &pwdata);
|
||||
|
||||
serverCertAuth.dbHandle = CERT_GetDefaultCertDB();
|
||||
|
@ -4,6 +4,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/UNIX.mk
|
||||
include $(CORE_DEPTH)/coreconf/Werror.mk
|
||||
|
||||
DEFAULT_COMPILER = gcc
|
||||
|
||||
@ -81,7 +82,7 @@ endif
|
||||
# definitions so that the linker can catch multiply-defined symbols.
|
||||
# Also, common symbols are not allowed with Darwin dynamic libraries.
|
||||
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK $(DARWIN_SDK_CFLAGS)
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(WARNING_CFLAGS) -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK $(DARWIN_SDK_CFLAGS)
|
||||
|
||||
ifdef BUILD_OPT
|
||||
ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
|
||||
|
@ -4,6 +4,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/UNIX.mk
|
||||
include $(CORE_DEPTH)/coreconf/Werror.mk
|
||||
|
||||
#
|
||||
# The default implementation strategy for Linux is now pthreads
|
||||
@ -25,17 +26,23 @@ DEFAULT_COMPILER = gcc
|
||||
ifeq ($(OS_TARGET),Android)
|
||||
ifndef ANDROID_NDK
|
||||
$(error Must set ANDROID_NDK to the path to the android NDK first)
|
||||
endif
|
||||
ifndef ANDROID_TOOLCHAIN_VERSION
|
||||
$(error Must set ANDROID_TOOLCHAIN_VERSION to the requested version number)
|
||||
endif
|
||||
ANDROID_PREFIX=$(OS_TEST)-linux-androideabi
|
||||
ANDROID_TARGET=$(ANDROID_PREFIX)-4.4.3
|
||||
ANDROID_TARGET=$(ANDROID_PREFIX)-$(ANDROID_TOOLCHAIN_VERSION)
|
||||
# should autodetect which linux we are on, currently android only
|
||||
# supports linux-x86 prebuilts
|
||||
ANDROID_TOOLCHAIN=$(ANDROID_NDK)/toolchains/$(ANDROID_TARGET)/prebuilt/linux-x86
|
||||
ANDROID_SYSROOT=$(ANDROID_NDK)/platforms/android-$(OS_TARGET_RELEASE)/arch-$(OS_TEST)
|
||||
ANDROID_CC=$(ANDROID_TOOLCHAIN)/bin/$(ANDROID_PREFIX)-gcc
|
||||
ANDROID_CCC=$(ANDROID_TOOLCHAIN)/bin/$(ANDROID_PREFIX)-g++
|
||||
NSS_DISABLE_GTESTS=1
|
||||
# internal tools need to be built with the native compiler
|
||||
ifndef INTERNAL_TOOLS
|
||||
CC = $(ANDROID_CC) --sysroot=$(ANDROID_SYSROOT)
|
||||
CCC = $(ANDROID_CCC) --sysroot=$(ANDROID_SYSROOT)
|
||||
DEFAULT_COMPILER=$(ANDROID_PREFIX)-gcc
|
||||
ARCHFLAG = --sysroot=$(ANDROID_SYSROOT)
|
||||
DEFINES += -DNO_SYSINFO -DNO_FORK_CHECK -DANDROID
|
||||
@ -126,57 +133,16 @@ endif
|
||||
endif
|
||||
|
||||
ifndef COMPILER_TAG
|
||||
COMPILER_TAG = _$(shell $(CC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q')
|
||||
CCC_COMPILER_TAG = _$(shell $(CCC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q')
|
||||
COMPILER_TAG := _$(CC_NAME)
|
||||
endif
|
||||
|
||||
ifeq ($(USE_PTHREADS),1)
|
||||
OS_PTHREAD = -lpthread
|
||||
endif
|
||||
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -Wall -Werror -pipe -ffunction-sections -fdata-sections -DLINUX -Dlinux -DHAVE_STRERROR
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) $(WARNING_CFLAGS) -pipe -ffunction-sections -fdata-sections -DLINUX -Dlinux -DHAVE_STRERROR
|
||||
OS_LIBS = $(OS_PTHREAD) -ldl -lc
|
||||
|
||||
ifeq ($(COMPILER_TAG),_clang)
|
||||
# -Qunused-arguments : clang objects to arguments that it doesn't understand
|
||||
# and fixing this would require rearchitecture
|
||||
# -Wno-parentheses-equality : because clang warns about macro expansions
|
||||
OS_CFLAGS += -Qunused-arguments -Wno-parentheses-equality
|
||||
ifdef BUILD_OPT
|
||||
# clang is unable to handle glib's expansion of strcmp and similar for optimized
|
||||
# builds, so ignore the resulting errors.
|
||||
# See https://llvm.org/bugs/show_bug.cgi?id=20144
|
||||
OS_CFLAGS += -Wno-array-bounds -Wno-unevaluated-expression
|
||||
endif
|
||||
# Clang reports its version as an older gcc, but it's OK
|
||||
NSS_HAS_GCC48 = true
|
||||
endif
|
||||
|
||||
# Check for the existence of gcc 4.8
|
||||
ifndef NSS_HAS_GCC48
|
||||
define GCC48_TEST =
|
||||
int main() {\n
|
||||
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)\n
|
||||
return 1;\n
|
||||
#else\n
|
||||
return 0;\n
|
||||
#endif\n
|
||||
}\n
|
||||
endef
|
||||
TEST_GCC48 := /tmp/test_gcc48_$(shell echo $$$$)
|
||||
NSS_HAS_GCC48 := (,$(shell echo -e "$(GCC48_TEST)" > $(TEST_GCC48).c && \
|
||||
$(CC) -o $(TEST_GCC48) $(TEST_GCC48).c && \
|
||||
$(TEST_GCC48) && echo true || echo false; \
|
||||
rm -f $(TEST_GCC48) $(TEST_GCC48).c))
|
||||
export NSS_HAS_GCC48
|
||||
endif
|
||||
|
||||
ifeq (true,$(NSS_HAS_GCC48))
|
||||
# Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
|
||||
# Here, we disable use of that #pragma and the warnings it suppresses.
|
||||
OS_CFLAGS += -DNSS_NO_GCC48 -Wno-unused-variable
|
||||
endif
|
||||
|
||||
ifdef USE_PTHREADS
|
||||
DEFINES += -D_REENTRANT
|
||||
endif
|
||||
|
@ -113,19 +113,25 @@ ifdef NS_USE_GCC
|
||||
else
|
||||
OPTIMIZER += -O2
|
||||
endif
|
||||
DEFINES += -UDEBUG -U_DEBUG -DNDEBUG
|
||||
DEFINES += -UDEBUG -DNDEBUG
|
||||
else
|
||||
OPTIMIZER += -g
|
||||
NULLSTRING :=
|
||||
SPACE := $(NULLSTRING) # end of the line
|
||||
USERNAME := $(subst $(SPACE),_,$(USERNAME))
|
||||
USERNAME := $(subst -,_,$(USERNAME))
|
||||
DEFINES += -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USERNAME)
|
||||
DEFINES += -DDEBUG -UNDEBUG -DDEBUG_$(USERNAME)
|
||||
endif
|
||||
else # !NS_USE_GCC
|
||||
OS_CFLAGS += -W3 -nologo -D_CRT_SECURE_NO_WARNINGS \
|
||||
-D_CRT_NONSTDC_NO_WARNINGS
|
||||
OS_DLLFLAGS += -nologo -DLL -SUBSYSTEM:WINDOWS
|
||||
ifndef NSS_ENABLE_WERROR
|
||||
NSS_ENABLE_WERROR = 0
|
||||
endif
|
||||
ifeq ($(NSS_ENABLE_WERROR),1)
|
||||
OS_CFLAGS += -WX
|
||||
endif
|
||||
ifeq ($(_MSC_VER),$(_MSC_VER_6))
|
||||
ifndef MOZ_DEBUG_SYMBOLS
|
||||
OS_DLLFLAGS += -PDB:NONE
|
||||
@ -159,7 +165,7 @@ else # !NS_USE_GCC
|
||||
else
|
||||
OPTIMIZER += -O2
|
||||
endif
|
||||
DEFINES += -UDEBUG -U_DEBUG -DNDEBUG
|
||||
DEFINES += -UDEBUG -DNDEBUG
|
||||
DLLFLAGS += -OUT:$@
|
||||
ifdef MOZ_DEBUG_SYMBOLS
|
||||
ifdef MOZ_DEBUG_FLAGS
|
||||
@ -176,7 +182,7 @@ else # !NS_USE_GCC
|
||||
SPACE := $(NULLSTRING) # end of the line
|
||||
USERNAME := $(subst $(SPACE),_,$(USERNAME))
|
||||
USERNAME := $(subst -,_,$(USERNAME))
|
||||
DEFINES += -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USERNAME)
|
||||
DEFINES += -DDEBUG -UNDEBUG -DDEBUG_$(USERNAME)
|
||||
DLLFLAGS += -DEBUG -OUT:$@
|
||||
LDFLAGS += -DEBUG
|
||||
ifeq ($(_MSC_VER),$(_MSC_VER_6))
|
||||
@ -197,7 +203,8 @@ ifneq ($(_MSC_VER),$(_MSC_VER_6))
|
||||
# Disable C4267: conversion from 'size_t' to 'type', possible loss of data
|
||||
# Disable C4244: conversion from 'type1' to 'type2', possible loss of data
|
||||
# Disable C4018: 'expression' : signed/unsigned mismatch
|
||||
OS_CFLAGS += -w44267 -w44244 -w44018
|
||||
# Disable C4312: 'type cast': conversion from 'type1' to 'type2' of greater size
|
||||
OS_CFLAGS += -w44267 -w44244 -w44018 -w44312
|
||||
ifeq ($(_MSC_VER_GE_12),1)
|
||||
OS_CFLAGS += -FS
|
||||
endif
|
||||
|
76
security/nss/coreconf/Werror.mk
Normal file
76
security/nss/coreconf/Werror.mk
Normal file
@ -0,0 +1,76 @@
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This sets warning flags for unix-like operating systems.
|
||||
|
||||
ifndef CC_NAME
|
||||
CC_NAME := $(shell $(CC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q')
|
||||
export CC_NAME
|
||||
endif
|
||||
|
||||
ifndef WARNING_CFLAGS
|
||||
# This tests to see if enabling the warning is possible before
|
||||
# setting an option to disable it.
|
||||
disable_warning = $(shell $(CC) -x c -E -Werror -W$(1) /dev/null >/dev/null 2>&1 && echo -Wno-$(1))
|
||||
|
||||
WARNING_CFLAGS = -Wall
|
||||
ifeq ($(CC_NAME),clang)
|
||||
# -Qunused-arguments : clang objects to arguments that it doesn't understand
|
||||
# and fixing this would require rearchitecture
|
||||
WARNING_CFLAGS += -Qunused-arguments
|
||||
# -Wno-parentheses-equality : because clang warns about macro expansions
|
||||
OS_CFLAGS += $(call disable_warning,parentheses-equality)
|
||||
ifdef BUILD_OPT
|
||||
# clang is unable to handle glib's expansion of strcmp and similar for optimized
|
||||
# builds, so ignore the resulting errors.
|
||||
# See https://llvm.org/bugs/show_bug.cgi?id=20144
|
||||
WARNING_CFLAGS += $(call disable_warning,array-bounds)
|
||||
WARNING_CFLAGS += $(call disable_warning,unevaluated-expression)
|
||||
endif
|
||||
endif # if clang
|
||||
|
||||
ifndef NSS_ENABLE_WERROR
|
||||
ifeq ($(OS_TARGET),Android)
|
||||
# Android lollipop generates the following warning:
|
||||
# error: call to 'sprintf' declared with attribute warning:
|
||||
# sprintf is often misused; please use snprintf [-Werror]
|
||||
# So, just suppress -Werror entirely on Android
|
||||
NSS_ENABLE_WERROR = 0
|
||||
$(warning OS_TARGET is Android, disabling -Werror)
|
||||
else
|
||||
ifeq ($(CC_NAME),clang)
|
||||
# Clang reports its version as an older gcc, but it's OK
|
||||
NSS_ENABLE_WERROR = 1
|
||||
else
|
||||
CC_VERSION := $(subst ., ,$(shell $(CC) -dumpversion))
|
||||
ifneq (,$(filter 4.8 4.9,$(word 1,$(CC_VERSION)).$(word 2,$(CC_VERSION))))
|
||||
NSS_ENABLE_WERROR = 1
|
||||
endif
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(CC_VERSION))))
|
||||
NSS_ENABLE_WERROR = 1
|
||||
endif
|
||||
ifndef NSS_ENABLE_WERROR
|
||||
$(warning Unable to find gcc 4.8 or greater, disabling -Werror)
|
||||
NSS_ENABLE_WERROR = 0
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif #ndef NSS_ENABLE_WERROR
|
||||
|
||||
ifeq ($(NSS_ENABLE_WERROR),1)
|
||||
WARNING_CFLAGS += -Werror
|
||||
# For gcc 6 and newer we need -Wno-error=misleading-indentation
|
||||
# to prevent compiler errors caused by mixed whitespace.
|
||||
CC_VERSION := $(subst ., ,$(shell $(CC) -dumpversion))
|
||||
ifeq (,$(filter 0 1 2 3 4 5,$(word 1,$(CC_VERSION))))
|
||||
WARNING_CFLAGS += -Wno-error=misleading-indentation
|
||||
endif
|
||||
else
|
||||
# Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
|
||||
# Use this to disable use of that #pragma and the warnings it suppresses.
|
||||
WARNING_CFLAGS += -DNSS_NO_GCC48
|
||||
endif
|
||||
export WARNING_CFLAGS
|
||||
endif # ndef WARNING_CFLAGS
|
@ -280,7 +280,12 @@ endif
|
||||
# IMPL_STRATEGY may be defined too.
|
||||
#
|
||||
|
||||
ifdef CROSS_COMPILE
|
||||
OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(LIBC_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJ
|
||||
else
|
||||
OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(COMPILER_TAG)$(LIBC_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJ
|
||||
endif
|
||||
|
||||
|
||||
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
|
||||
ifndef BUILD_OPT
|
||||
@ -289,7 +294,11 @@ ifndef BUILD_OPT
|
||||
# (RTL) in the debug build
|
||||
#
|
||||
ifdef USE_DEBUG_RTL
|
||||
ifdef CROSS_COMPILE
|
||||
OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJD
|
||||
else
|
||||
OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(COMPILER_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJD
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -184,7 +184,13 @@ DEFINES += -DUSE_UTIL_DIRECTLY
|
||||
USE_UTIL_DIRECTLY = 1
|
||||
|
||||
# Build with NO_NSPR_10_SUPPORT to avoid using obsolete NSPR features
|
||||
DEFINES += -DNO_NSPR_10_SUPPORT
|
||||
#DEFINES += -DNO_NSPR_10_SUPPORT
|
||||
|
||||
# Hide old, deprecated, TLS cipher suite names when building NSS
|
||||
DEFINES += -DSSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES
|
||||
|
||||
# build with NO_PKCS11_BYPASS by default
|
||||
ifndef NSS_PKCS11_BYPASS
|
||||
DEFINES += -DNO_PKCS11_BYPASS
|
||||
NSS_NO_PKCS11_BYPASS = 1
|
||||
endif
|
||||
|
@ -350,7 +350,7 @@ define2(char *name, char *val, struct inclist *file)
|
||||
/* Fast inline binary search */
|
||||
register char *s1;
|
||||
register char *s2;
|
||||
register int middle = (first + last) / 2;
|
||||
register int middle = first + (last - first) / 2;
|
||||
|
||||
/* Fast inline strchr() */
|
||||
s1 = name;
|
||||
@ -436,7 +436,7 @@ slookup(char *symbol, struct inclist *file)
|
||||
/* Fast inline binary search */
|
||||
register char *s1;
|
||||
register char *s2;
|
||||
register int middle = (first + last) / 2;
|
||||
register int middle = first + (last - first) / 2;
|
||||
|
||||
/* Fast inline strchr() */
|
||||
s1 = symbol;
|
||||
|
@ -424,12 +424,12 @@ $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.S
|
||||
$(OBJDIR)/$(PROG_PREFIX)%: %.cpp
|
||||
@$(MAKE_OBJDIR)
|
||||
ifdef USE_NT_C_SYNTAX
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
ifdef NEED_ABSOLUTE_PATH
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
$(CCC) -o $@ -c $(CFLAGS) $<
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -440,16 +440,16 @@ $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cc
|
||||
$(MAKE_OBJDIR)
|
||||
ifdef STRICT_CPLUSPLUS_SUFFIX
|
||||
echo "#line 1 \"$<\"" | cat - $< > $(OBJDIR)/t_$*.cc
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(OBJDIR)/t_$*.cc
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(OBJDIR)/t_$*.cc
|
||||
rm -f $(OBJDIR)/t_$*.cc
|
||||
else
|
||||
ifdef USE_NT_C_SYNTAX
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
ifdef NEED_ABSOLUTE_PATH
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
$(CCC) -o $@ -c $(CFLAGS) $<
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
endif #STRICT_CPLUSPLUS_SUFFIX
|
||||
@ -458,22 +458,22 @@ $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cpp
|
||||
@$(MAKE_OBJDIR)
|
||||
ifdef STRICT_CPLUSPLUS_SUFFIX
|
||||
echo "#line 1 \"$<\"" | cat - $< > $(OBJDIR)/t_$*.cc
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(OBJDIR)/t_$*.cc
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(OBJDIR)/t_$*.cc
|
||||
rm -f $(OBJDIR)/t_$*.cc
|
||||
else
|
||||
ifdef USE_NT_C_SYNTAX
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -Fo$@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
ifdef NEED_ABSOLUTE_PATH
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<)
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
|
||||
else
|
||||
$(CCC) -o $@ -c $(CFLAGS) $<
|
||||
$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $<
|
||||
endif
|
||||
endif
|
||||
endif #STRICT_CPLUSPLUS_SUFFIX
|
||||
|
||||
%.i: %.cpp
|
||||
$(CCC) -C -E $(CFLAGS) $< > $@
|
||||
$(CCC) -C -E $(CFLAGS) $(CXXFLAGS) $< > $@
|
||||
|
||||
%.i: %.c
|
||||
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
|
||||
|
@ -1607,8 +1607,36 @@ done:
|
||||
"\x30\x05\x82\x03" ".nc" \
|
||||
"\x30\x05\x82\x03" ".tf" \
|
||||
|
||||
/* TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 */
|
||||
|
||||
#define TUBITAK1_SUBJECT_DN \
|
||||
"\x30\x81\xd2" \
|
||||
"\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02" \
|
||||
/* C */ "TR" \
|
||||
"\x31\x18\x30\x16\x06\x03\x55\x04\x07\x13\x0f" \
|
||||
/* L */ "Gebze - Kocaeli" \
|
||||
"\x31\x42\x30\x40\x06\x03\x55\x04\x0a\x13\x39" \
|
||||
/* O */ "Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK" \
|
||||
"\x31\x2d\x30\x2b\x06\x03\x55\x04\x0b\x13\x24" \
|
||||
/* OU */ "Kamu Sertifikasyon Merkezi - Kamu SM" \
|
||||
"\x31\x36\x30\x34\x06\x03\x55\x04\x03\x13\x2d" \
|
||||
/* CN */ "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
|
||||
|
||||
#define TUBITAK1_NAME_CONSTRAINTS \
|
||||
"\x30\x65\xa0\x63" \
|
||||
"\x30\x09\x82\x07" ".gov.tr" \
|
||||
"\x30\x09\x82\x07" ".k12.tr" \
|
||||
"\x30\x09\x82\x07" ".pol.tr" \
|
||||
"\x30\x09\x82\x07" ".mil.tr" \
|
||||
"\x30\x09\x82\x07" ".tsk.tr" \
|
||||
"\x30\x09\x82\x07" ".kep.tr" \
|
||||
"\x30\x09\x82\x07" ".bel.tr" \
|
||||
"\x30\x09\x82\x07" ".edu.tr" \
|
||||
"\x30\x09\x82\x07" ".org.tr"
|
||||
|
||||
static const SECItem builtInNameConstraints[][2] = {
|
||||
NAME_CONSTRAINTS_ENTRY(ANSSI)
|
||||
NAME_CONSTRAINTS_ENTRY(ANSSI),
|
||||
NAME_CONSTRAINTS_ENTRY(TUBITAK1)
|
||||
};
|
||||
|
||||
SECStatus
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "secport.h"
|
||||
#include "seccomon.h"
|
||||
#include "secoid.h"
|
||||
#include "sslerr.h"
|
||||
#include "genname.h"
|
||||
#include "keyhi.h"
|
||||
#include "cert.h"
|
||||
@ -23,6 +22,7 @@
|
||||
#include "pkim.h"
|
||||
#include "pki3hack.h"
|
||||
#include "base.h"
|
||||
#include "keyhi.h"
|
||||
|
||||
/*
|
||||
* Check the validity times of a certificate
|
||||
@ -34,6 +34,94 @@ CERT_CertTimesValid(CERTCertificate *c)
|
||||
return (valid == secCertTimeValid) ? SECSuccess : SECFailure;
|
||||
}
|
||||
|
||||
SECStatus checkKeyParams(const SECAlgorithmID *sigAlgorithm, const SECKEYPublicKey *key)
|
||||
{
|
||||
SECStatus rv;
|
||||
SECOidTag sigAlg;
|
||||
SECOidTag curve;
|
||||
PRUint32 policyFlags = 0;
|
||||
PRInt32 minLen, len;
|
||||
|
||||
sigAlg = SECOID_GetAlgorithmTag(sigAlgorithm);
|
||||
|
||||
switch(sigAlg) {
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
|
||||
case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
|
||||
if (key->keyType != ecKey) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
curve = SECKEY_GetECCOid(&key->u.ec.DEREncodedParams);
|
||||
if (curve != 0) {
|
||||
if (NSS_GetAlgorithmPolicy(curve, &policyFlags) == SECFailure ||
|
||||
!(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
|
||||
PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
|
||||
return SECFailure;
|
||||
} else {
|
||||
return SECSuccess;
|
||||
}
|
||||
} else {
|
||||
PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
|
||||
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
|
||||
case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
|
||||
case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
|
||||
if (key->keyType != rsaKey && key->keyType != rsaPssKey) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
len = 8 * key->u.rsa.modulus.len;
|
||||
|
||||
rv = NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minLen);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (len < minLen) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
|
||||
case SEC_OID_SDN702_DSA_SIGNATURE:
|
||||
case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
|
||||
case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
|
||||
if (key->keyType != dsaKey) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
len = 8 * key->u.dsa.params.prime.len;
|
||||
|
||||
rv = NSS_OptionGet(NSS_DSA_MIN_KEY_SIZE, &minLen);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (len < minLen) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
default:
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* verify the signature of a signed data object with the given DER publickey
|
||||
*/
|
||||
@ -50,7 +138,6 @@ CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd,
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* check the signature */
|
||||
sig = sd->signature;
|
||||
/* convert sig->len from bit counts to byte count. */
|
||||
@ -61,11 +148,17 @@ CERT_VerifySignedDataWithPublicKey(const CERTSignedData *sd,
|
||||
if (rv == SECSuccess) {
|
||||
/* Are we honoring signatures for this algorithm? */
|
||||
PRUint32 policyFlags = 0;
|
||||
rv = checkKeyParams(&sd->signatureAlgorithm, pubKey);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = NSS_GetAlgorithmPolicy(hashAlg, &policyFlags);
|
||||
if (rv == SECSuccess &&
|
||||
!(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
|
||||
PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
|
||||
rv = SECFailure;
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -1454,7 +1454,6 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
|
||||
CERTCertListNode *node;
|
||||
PKIX_PL_Cert *certPkix = NULL;
|
||||
PKIX_TrustAnchor *trustAnchor = NULL;
|
||||
PKIX_PL_Date *revDate = NULL;
|
||||
PKIX_RevocationChecker *revChecker = NULL;
|
||||
PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext;
|
||||
|
||||
@ -1664,9 +1663,6 @@ cert_pkixSetParam(PKIX_ProcessingParams *procParams,
|
||||
if (date != NULL)
|
||||
PKIX_PL_Object_DecRef((PKIX_PL_Object *)date, plContext);
|
||||
|
||||
if (revDate != NULL)
|
||||
PKIX_PL_Object_DecRef((PKIX_PL_Object *)revDate, plContext);
|
||||
|
||||
if (revChecker != NULL)
|
||||
PKIX_PL_Object_DecRef((PKIX_PL_Object *)revChecker, plContext);
|
||||
|
||||
|
@ -543,7 +543,7 @@ CERT_CreateEncodedOCSPSuccessResponse(
|
||||
done:
|
||||
if (privKey)
|
||||
SECKEY_DestroyPrivateKey(privKey);
|
||||
if (br->responseSignature.signature.data)
|
||||
if (br && br->responseSignature.signature.data)
|
||||
SECITEM_FreeItem(&br->responseSignature.signature, PR_FALSE);
|
||||
PORT_FreeArena(tmpArena, PR_FALSE);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -45,8 +45,8 @@
|
||||
* of the comment in the CK_VERSION type definition.
|
||||
*/
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 5
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION "2.5"
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 6
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION "2.6"
|
||||
|
||||
/* These version numbers detail the semantic changes to the ckfw engine. */
|
||||
#define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1
|
||||
|
@ -85,9 +85,9 @@ nssCKFWHash_Create
|
||||
rv->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
|
||||
if (!rv->mutex) {
|
||||
if( CKR_OK == *pError ) {
|
||||
(void)nss_ZFreeIf(rv);
|
||||
*pError = CKR_GENERAL_ERROR;
|
||||
}
|
||||
(void)nss_ZFreeIf(rv);
|
||||
return (nssCKFWHash *)NULL;
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,7 @@ nssCKFWObject_Create
|
||||
if( CKR_OK == *pError ) {
|
||||
*pError = CKR_GENERAL_ERROR;
|
||||
}
|
||||
nss_ZFreeIf(fwObject);
|
||||
return (NSSCKFWObject *)NULL;
|
||||
}
|
||||
|
||||
|
@ -260,6 +260,14 @@ extern int SECKEY_ECParamsToKeySize(const SECItem *params);
|
||||
*/
|
||||
extern int SECKEY_ECParamsToBasePointOrderLen(const SECItem *params);
|
||||
|
||||
/*
|
||||
* Returns the object identifier of the curve, of the provided
|
||||
* elliptic curve parameters structures.
|
||||
*
|
||||
* Return 0 on failure (unknown EC domain parameters).
|
||||
*/
|
||||
SECOidTag SECKEY_GetECCOid(const SECKEYECParams * params);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _KEYHI_H_ */
|
||||
|
@ -618,6 +618,12 @@ seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
|
||||
if (rv == SECSuccess) return pubk;
|
||||
break;
|
||||
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
||||
/* A basic sanity check on inputs. */
|
||||
if (spki->algorithm.parameters.len == 0 || newOs.len == 0) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
break;
|
||||
}
|
||||
|
||||
pubk->keyType = ecKey;
|
||||
pubk->u.ec.size = 0;
|
||||
|
||||
@ -1904,3 +1910,22 @@ SECKEY_CacheStaticFlags(SECKEYPrivateKey* key)
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECOidTag
|
||||
SECKEY_GetECCOid(const SECKEYECParams * params)
|
||||
{
|
||||
SECItem oid = { siBuffer, NULL, 0};
|
||||
SECOidData *oidData = NULL;
|
||||
|
||||
/*
|
||||
* params->data needs to contain the ASN encoding of an object ID (OID)
|
||||
* representing a named curve. Here, we strip away everything
|
||||
* before the actual OID and use the OID to look up a named curve.
|
||||
*/
|
||||
if (params->data[0] != SEC_ASN1_OBJECT_ID) return 0;
|
||||
oid.len = params->len - 2;
|
||||
oid.data = params->data + 2;
|
||||
if ((oidData = SECOID_FindOID(&oid)) == NULL) return 0;
|
||||
|
||||
return oidData->offset;
|
||||
}
|
||||
|
@ -413,6 +413,7 @@ SGN_Digest(SECKEYPrivateKey *privKey,
|
||||
}
|
||||
result->len = modulusLen;
|
||||
result->data = (unsigned char*) PORT_Alloc(modulusLen);
|
||||
result->type = siBuffer;
|
||||
|
||||
if (result->data == NULL) {
|
||||
rv = SECFailure;
|
||||
|
126
security/nss/lib/dbm/include/cdefs.h
Normal file
126
security/nss/lib/dbm/include/cdefs.h
Normal file
@ -0,0 +1,126 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Berkeley Software Design, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. ***REMOVED*** - see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cdefs.h 8.7 (Berkeley) 1/21/94
|
||||
*/
|
||||
|
||||
#ifndef _CDEFS_H_
|
||||
#define _CDEFS_H_
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#define __BEGIN_DECLS extern "C" {
|
||||
#define __END_DECLS }
|
||||
#else
|
||||
#define __BEGIN_DECLS
|
||||
#define __END_DECLS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The __CONCAT macro is used to concatenate parts of symbol names, e.g.
|
||||
* with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
|
||||
* The __CONCAT macro is a bit tricky -- make sure you don't put spaces
|
||||
* in between its arguments. __CONCAT can also concatenate double-quoted
|
||||
* strings produced by the __STRING macro, but this only works with ANSI C.
|
||||
*/
|
||||
#if defined(__STDC__) || defined(__cplusplus) || defined(_WINDOWS) || defined(XP_OS2)
|
||||
#define __P(protos) protos /* full-blown ANSI C */
|
||||
#define __CONCAT(x,y) x ## y
|
||||
#define __STRING(x) #x
|
||||
|
||||
/* On HP-UX 11.00, <sys/stdsyms.h> defines __const. */
|
||||
#ifndef __const
|
||||
#define __const const /* define reserved names to standard */
|
||||
#endif /* __const */
|
||||
#define __signed signed
|
||||
#define __volatile volatile
|
||||
#ifndef _WINDOWS
|
||||
#if defined(__cplusplus)
|
||||
#define __inline inline /* convert to C++ keyword */
|
||||
#else
|
||||
#if !defined(__GNUC__) && !defined(__MWERKS__)
|
||||
#define __inline /* delete GCC keyword */
|
||||
#endif /* !__GNUC__ */
|
||||
#endif /* !__cplusplus */
|
||||
#endif /* !_WINDOWS */
|
||||
|
||||
#else /* !(__STDC__ || __cplusplus) */
|
||||
#define __P(protos) () /* traditional C preprocessor */
|
||||
#define __CONCAT(x,y) x/**/y
|
||||
#define __STRING(x) "x"
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __const /* delete pseudo-ANSI C keywords */
|
||||
#define __inline
|
||||
#define __signed
|
||||
#define __volatile
|
||||
/*
|
||||
* In non-ANSI C environments, new programs will want ANSI-only C keywords
|
||||
* deleted from the program and old programs will want them left alone.
|
||||
* When using a compiler other than gcc, programs using the ANSI C keywords
|
||||
* const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
|
||||
* When using "gcc -traditional", we assume that this is the intent; if
|
||||
* __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
|
||||
*/
|
||||
#ifndef NO_ANSI_KEYWORDS
|
||||
#define const /* delete ANSI C keywords */
|
||||
#define inline
|
||||
#define signed
|
||||
#define volatile
|
||||
#endif
|
||||
#endif /* !__GNUC__ */
|
||||
#endif /* !(__STDC__ || __cplusplus) */
|
||||
|
||||
/*
|
||||
* GCC1 and some versions of GCC2 declare dead (non-returning) and
|
||||
* pure (no side effects) functions using "volatile" and "const";
|
||||
* unfortunately, these then cause warnings under "-ansi -pedantic".
|
||||
* GCC2 uses a new, peculiar __attribute__((attrs)) style. All of
|
||||
* these work for GNU C++ (modulo a slight glitch in the C++ grammar
|
||||
* in the distribution version of 2.5.5).
|
||||
*/
|
||||
#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 5
|
||||
#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define __dead __volatile
|
||||
#define __pure __const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Delete pseudo-keywords wherever they are not available or needed. */
|
||||
#ifndef __dead
|
||||
#define __dead
|
||||
#define __pure
|
||||
#endif
|
||||
|
||||
#endif /* !_CDEFS_H_ */
|
97
security/nss/lib/dbm/include/mpool.h
Normal file
97
security/nss/lib/dbm/include/mpool.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. ***REMOVED*** - see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mpool.h 8.2 (Berkeley) 7/14/94
|
||||
*/
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
/*
|
||||
* The memory pool scheme is a simple one. Each in-memory page is referenced
|
||||
* by a bucket which is threaded in up to two of three ways. All active pages
|
||||
* are threaded on a hash chain (hashed by page number) and an lru chain.
|
||||
* Inactive pages are threaded on a free chain. Each reference to a memory
|
||||
* pool is handed an opaque MPOOL cookie which stores all of this information.
|
||||
*/
|
||||
#define HASHSIZE 128
|
||||
#define HASHKEY(pgno) ((pgno - 1) % HASHSIZE)
|
||||
|
||||
/* The BKT structures are the elements of the queues. */
|
||||
typedef struct _bkt {
|
||||
CIRCLEQ_ENTRY(_bkt) hq; /* hash queue */
|
||||
CIRCLEQ_ENTRY(_bkt) q; /* lru queue */
|
||||
void *page; /* page */
|
||||
pgno_t pgno; /* page number */
|
||||
|
||||
#define MPOOL_DIRTY 0x01 /* page needs to be written */
|
||||
#define MPOOL_PINNED 0x02 /* page is pinned into memory */
|
||||
uint8 flags; /* flags */
|
||||
} BKT;
|
||||
|
||||
typedef struct MPOOL {
|
||||
CIRCLEQ_HEAD(_lqh, _bkt) lqh; /* lru queue head */
|
||||
/* hash queue array */
|
||||
CIRCLEQ_HEAD(_hqh, _bkt) hqh[HASHSIZE];
|
||||
pgno_t curcache; /* current number of cached pages */
|
||||
pgno_t maxcache; /* max number of cached pages */
|
||||
pgno_t npages; /* number of pages in the file */
|
||||
uint32 pagesize; /* file page size */
|
||||
int fd; /* file descriptor */
|
||||
/* page in conversion routine */
|
||||
void (*pgin) (void *, pgno_t, void *);
|
||||
/* page out conversion routine */
|
||||
void (*pgout) (void *, pgno_t, void *);
|
||||
void *pgcookie; /* cookie for page in/out routines */
|
||||
#ifdef STATISTICS
|
||||
uint32 cachehit;
|
||||
uint32 cachemiss;
|
||||
uint32 pagealloc;
|
||||
uint32 pageflush;
|
||||
uint32 pageget;
|
||||
uint32 pagenew;
|
||||
uint32 pageput;
|
||||
uint32 pageread;
|
||||
uint32 pagewrite;
|
||||
#endif
|
||||
} MPOOL;
|
||||
|
||||
__BEGIN_DECLS
|
||||
MPOOL *mpool_open (void *, int, pgno_t, pgno_t);
|
||||
void mpool_filter (MPOOL *, void (*)(void *, pgno_t, void *),
|
||||
void (*)(void *, pgno_t, void *), void *);
|
||||
void *mpool_new (MPOOL *, pgno_t *);
|
||||
void *mpool_get (MPOOL *, pgno_t, uint);
|
||||
int mpool_put (MPOOL *, void *, uint);
|
||||
int mpool_sync (MPOOL *);
|
||||
int mpool_close (MPOOL *);
|
||||
#ifdef STATISTICS
|
||||
void mpool_stat (MPOOL *);
|
||||
#endif
|
||||
__END_DECLS
|
@ -158,10 +158,11 @@ long new_lseek(int fd, long offset, int origin)
|
||||
{
|
||||
char buffer[1024];
|
||||
long len = seek_pos-end_pos;
|
||||
memset(&buffer, 0, 1024);
|
||||
memset(buffer, 0, 1024);
|
||||
while(len > 0)
|
||||
{
|
||||
write(fd, (char*)&buffer, (size_t)(1024 > len ? len : 1024));
|
||||
if(write(fd, buffer, (size_t)(1024 > len ? len : 1024)) < 0)
|
||||
return(-1);
|
||||
len -= 1024;
|
||||
}
|
||||
return(lseek(fd, seek_pos, SEEK_SET));
|
||||
@ -981,7 +982,7 @@ overflow_page(HTAB *hashp)
|
||||
if (offset > SPLITMASK) {
|
||||
if (++splitnum >= NCACHED) {
|
||||
#ifndef macintosh
|
||||
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
|
||||
(void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
@ -996,7 +997,7 @@ overflow_page(HTAB *hashp)
|
||||
free_page++;
|
||||
if (free_page >= NCACHED) {
|
||||
#ifndef macintosh
|
||||
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
|
||||
(void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
@ -1022,8 +1023,7 @@ overflow_page(HTAB *hashp)
|
||||
if (offset > SPLITMASK) {
|
||||
if (++splitnum >= NCACHED) {
|
||||
#ifndef macintosh
|
||||
(void)write(STDERR_FILENO, OVMSG,
|
||||
sizeof(OVMSG) - 1);
|
||||
(void)fwrite(OVMSG, 1, sizeof(OVMSG) - 1, stderr);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
@ -911,7 +911,7 @@ hash_seq(
|
||||
uint flag)
|
||||
{
|
||||
register uint32 bucket;
|
||||
register BUFHEAD *bufp;
|
||||
register BUFHEAD *bufp = NULL;
|
||||
HTAB *hashp;
|
||||
uint16 *bp, ndx;
|
||||
|
||||
|
@ -579,6 +579,7 @@ get_token_objects_for_cache (
|
||||
&numObjects,
|
||||
&status);
|
||||
if (status != PR_SUCCESS) {
|
||||
nss_ZFreeIf(objects);
|
||||
return status;
|
||||
}
|
||||
for (i=0; i<numObjects; i++) {
|
||||
|
@ -479,6 +479,31 @@ ifndef NSS_DISABLE_ECC
|
||||
endif
|
||||
endif
|
||||
|
||||
# poly1305-donna-x64-sse2-incremental-source.c requires __int128 support
|
||||
# in GCC 4.6.0.
|
||||
ifeq ($(CC_NAME),clang)
|
||||
HAVE_INT128_SUPPORT = 1
|
||||
else ifeq (1,$(CC_IS_GCC))
|
||||
ifneq (,$(filter 4.6 4.7 4.8 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
|
||||
HAVE_INT128_SUPPORT = 1
|
||||
endif
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
|
||||
HAVE_INT128_SUPPORT = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CPU_ARCH),x86_64)
|
||||
ifdef HAVE_INT128_SUPPORT
|
||||
EXTRA_SRCS += poly1305-donna-x64-sse2-incremental-source.c
|
||||
else
|
||||
EXTRA_SRCS += poly1305.c
|
||||
endif
|
||||
EXTRA_SRCS += chacha20_vec.c
|
||||
else
|
||||
EXTRA_SRCS += poly1305.c
|
||||
EXTRA_SRCS += chacha20.c
|
||||
endif # x86_64
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
@ -559,7 +584,7 @@ SINGLE_SHLIB_DIR = $(OBJDIR)/$(OS_TARGET)_SINGLE_SHLIB
|
||||
ALL_TRASH += $(SINGLE_SHLIB_DIR)
|
||||
|
||||
$(SINGLE_SHLIB_DIR):
|
||||
-mkdir $(SINGLE_SHLIB_DIR)
|
||||
-mkdir -p $(SINGLE_SHLIB_DIR)
|
||||
|
||||
release_md libs:: $(SINGLE_SHLIB_DIR)
|
||||
$(MAKE) FREEBL_CHILD_BUILD=1 \
|
||||
|
@ -986,6 +986,35 @@ Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
** ChaCha20+Poly1305 AEAD
|
||||
*/
|
||||
|
||||
extern SECStatus ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
unsigned int tagLen);
|
||||
|
||||
extern ChaCha20Poly1305Context *ChaCha20Poly1305_CreateContext(
|
||||
const unsigned char *key, unsigned int keyLen, unsigned int tagLen);
|
||||
|
||||
extern void ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx,
|
||||
PRBool freeit);
|
||||
|
||||
extern SECStatus ChaCha20Poly1305_Seal(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
extern SECStatus ChaCha20Poly1305_Open(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
@ -1444,6 +1473,12 @@ FIPS186Change_ReduceModQForDSA(const unsigned char *w,
|
||||
const unsigned char *q,
|
||||
unsigned char *xj);
|
||||
|
||||
/* To allow NIST KAT tests */
|
||||
extern SECStatus
|
||||
PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len,
|
||||
const PRUint8 *nonce, unsigned int nonce_len,
|
||||
const PRUint8 *personal_string, unsigned int ps_len);
|
||||
|
||||
/*
|
||||
* The following functions are for FIPS poweron self test and FIPS algorithm
|
||||
* testing.
|
||||
|
@ -222,6 +222,7 @@ struct SHA256ContextStr ;
|
||||
struct SHA512ContextStr ;
|
||||
struct AESKeyWrapContextStr ;
|
||||
struct SEEDContextStr ;
|
||||
struct ChaCha20Poly1305ContextStr;
|
||||
|
||||
typedef struct DESContextStr DESContext;
|
||||
typedef struct RC2ContextStr RC2Context;
|
||||
@ -240,6 +241,7 @@ typedef struct SHA512ContextStr SHA512Context;
|
||||
typedef struct SHA512ContextStr SHA384Context;
|
||||
typedef struct AESKeyWrapContextStr AESKeyWrapContext;
|
||||
typedef struct SEEDContextStr SEEDContext;
|
||||
typedef struct ChaCha20Poly1305ContextStr ChaCha20Poly1305Context;
|
||||
|
||||
/***************************************************************************
|
||||
** RSA Public and Private Key structures
|
||||
|
111
security/nss/lib/freebl/chacha20.c
Normal file
111
security/nss/lib/freebl/chacha20.c
Normal file
@ -0,0 +1,111 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Adopted from the public domain code in NaCl by djb. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "secport.h"
|
||||
#include "chacha20.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma intrinsic(_lrotl)
|
||||
#define ROTL32(x, n) _lrotl(x, n)
|
||||
#else
|
||||
#define ROTL32(x, n) ((x << n) | (x >> ((8 * sizeof x) - n)))
|
||||
#endif
|
||||
|
||||
#define ROTATE(v, c) ROTL32((v), (c))
|
||||
|
||||
#define U32TO8_LITTLE(p, v) \
|
||||
{ (p)[0] = ((v) ) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \
|
||||
(p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; }
|
||||
#define U8TO32_LITTLE(p) \
|
||||
(((PRUint32)((p)[0]) ) | ((PRUint32)((p)[1]) << 8) | \
|
||||
((PRUint32)((p)[2]) << 16) | ((PRUint32)((p)[3]) << 24))
|
||||
|
||||
#define QUARTERROUND(x, a, b, c, d) \
|
||||
x[a] = x[a] + x[b]; x[d] = ROTATE(x[d] ^ x[a], 16); \
|
||||
x[c] = x[c] + x[d]; x[b] = ROTATE(x[b] ^ x[c], 12); \
|
||||
x[a] = x[a] + x[b]; x[d] = ROTATE(x[d] ^ x[a], 8); \
|
||||
x[c] = x[c] + x[d]; x[b] = ROTATE(x[b] ^ x[c], 7);
|
||||
|
||||
static void
|
||||
ChaChaCore(unsigned char output[64], const PRUint32 input[16], int num_rounds)
|
||||
{
|
||||
PRUint32 x[16];
|
||||
int i;
|
||||
|
||||
PORT_Memcpy(x, input, sizeof(PRUint32) * 16);
|
||||
for (i = num_rounds; i > 0; i -= 2) {
|
||||
QUARTERROUND(x, 0, 4, 8, 12)
|
||||
QUARTERROUND(x, 1, 5, 9, 13)
|
||||
QUARTERROUND(x, 2, 6, 10, 14)
|
||||
QUARTERROUND(x, 3, 7, 11, 15)
|
||||
QUARTERROUND(x, 0, 5, 10, 15)
|
||||
QUARTERROUND(x, 1, 6, 11, 12)
|
||||
QUARTERROUND(x, 2, 7, 8, 13)
|
||||
QUARTERROUND(x, 3, 4, 9, 14)
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
x[i] = x[i] + input[i];
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
U32TO8_LITTLE(output + 4 * i, x[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char sigma[16] = "expand 32-byte k";
|
||||
|
||||
void
|
||||
ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inLen,
|
||||
const unsigned char key[32], const unsigned char nonce[12],
|
||||
uint32_t counter)
|
||||
{
|
||||
unsigned char block[64];
|
||||
PRUint32 input[16];
|
||||
unsigned int i;
|
||||
|
||||
input[4] = U8TO32_LITTLE(key + 0);
|
||||
input[5] = U8TO32_LITTLE(key + 4);
|
||||
input[6] = U8TO32_LITTLE(key + 8);
|
||||
input[7] = U8TO32_LITTLE(key + 12);
|
||||
|
||||
input[8] = U8TO32_LITTLE(key + 16);
|
||||
input[9] = U8TO32_LITTLE(key + 20);
|
||||
input[10] = U8TO32_LITTLE(key + 24);
|
||||
input[11] = U8TO32_LITTLE(key + 28);
|
||||
|
||||
input[0] = U8TO32_LITTLE(sigma + 0);
|
||||
input[1] = U8TO32_LITTLE(sigma + 4);
|
||||
input[2] = U8TO32_LITTLE(sigma + 8);
|
||||
input[3] = U8TO32_LITTLE(sigma + 12);
|
||||
|
||||
input[12] = counter;
|
||||
input[13] = U8TO32_LITTLE(nonce + 0);
|
||||
input[14] = U8TO32_LITTLE(nonce + 4);
|
||||
input[15] = U8TO32_LITTLE(nonce + 8);
|
||||
|
||||
while (inLen >= 64) {
|
||||
ChaChaCore(block, input, 20);
|
||||
for (i = 0; i < 64; i++) {
|
||||
out[i] = in[i] ^ block[i];
|
||||
}
|
||||
|
||||
input[12]++;
|
||||
inLen -= 64;
|
||||
in += 64;
|
||||
out += 64;
|
||||
}
|
||||
|
||||
if (inLen > 0) {
|
||||
ChaChaCore(block, input, 20);
|
||||
for (i = 0; i < inLen; i++) {
|
||||
out[i] = in[i] ^ block[i];
|
||||
}
|
||||
}
|
||||
}
|
26
security/nss/lib/freebl/chacha20.h
Normal file
26
security/nss/lib/freebl/chacha20.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* chacha20.h - header file for ChaCha20 implementation.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef FREEBL_CHACHA20_H_
|
||||
#define FREEBL_CHACHA20_H_
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
#include "prtypes.h"
|
||||
typedef PRUint32 uint32_t;
|
||||
typedef PRUint64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* ChaCha20XOR encrypts |inLen| bytes from |in| with the given key and
|
||||
* nonce and writes the result to |out|, which may be equal to |in|. The
|
||||
* initial block counter is specified by |counter|. */
|
||||
extern void ChaCha20XOR(unsigned char *out, const unsigned char *in,
|
||||
unsigned int inLen, const unsigned char key[32],
|
||||
const unsigned char nonce[12], uint32_t counter);
|
||||
|
||||
#endif /* FREEBL_CHACHA20_H_ */
|
278
security/nss/lib/freebl/chacha20_vec.c
Normal file
278
security/nss/lib/freebl/chacha20_vec.c
Normal file
@ -0,0 +1,278 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* This implementation is by Ted Krovetz and was submitted to SUPERCOP and
|
||||
* marked as public domain. It was been altered to allow for non-aligned inputs
|
||||
* and to allow the block counter to be passed in specifically. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "chacha20.h"
|
||||
|
||||
#ifndef CHACHA_RNDS
|
||||
#define CHACHA_RNDS 20 /* 8 (high speed), 20 (conservative), 12 (middle) */
|
||||
#endif
|
||||
|
||||
/* Architecture-neutral way to specify 16-byte vector of ints */
|
||||
typedef unsigned vec __attribute__ ((vector_size (16)));
|
||||
|
||||
/* This implementation is designed for Neon, SSE and AltiVec machines. The
|
||||
* following specify how to do certain vector operations efficiently on
|
||||
* each architecture, using intrinsics.
|
||||
* This implementation supports parallel processing of multiple blocks,
|
||||
* including potentially using general-purpose registers.
|
||||
*/
|
||||
#if __ARM_NEON__
|
||||
#include <arm_neon.h>
|
||||
#define GPR_TOO 1
|
||||
#define VBPI 2
|
||||
#define ONE (vec)vsetq_lane_u32(1,vdupq_n_u32(0),0)
|
||||
#define LOAD(m) (vec)(*((vec*)(m)))
|
||||
#define STORE(m,r) (*((vec*)(m))) = (r)
|
||||
#define ROTV1(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,1)
|
||||
#define ROTV2(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,2)
|
||||
#define ROTV3(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,3)
|
||||
#define ROTW16(x) (vec)vrev32q_u16((uint16x8_t)x)
|
||||
#if __clang__
|
||||
#define ROTW7(x) (x << ((vec){ 7, 7, 7, 7})) ^ (x >> ((vec){25,25,25,25}))
|
||||
#define ROTW8(x) (x << ((vec){ 8, 8, 8, 8})) ^ (x >> ((vec){24,24,24,24}))
|
||||
#define ROTW12(x) (x << ((vec){12,12,12,12})) ^ (x >> ((vec){20,20,20,20}))
|
||||
#else
|
||||
#define ROTW7(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,7),(uint32x4_t)x,25)
|
||||
#define ROTW8(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,8),(uint32x4_t)x,24)
|
||||
#define ROTW12(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,12),(uint32x4_t)x,20)
|
||||
#endif
|
||||
#elif __SSE2__
|
||||
#include <emmintrin.h>
|
||||
#define GPR_TOO 0
|
||||
#if __clang__
|
||||
#define VBPI 4
|
||||
#else
|
||||
#define VBPI 3
|
||||
#endif
|
||||
#define ONE (vec)_mm_set_epi32(0,0,0,1)
|
||||
#define LOAD(m) (vec)_mm_loadu_si128((__m128i*)(m))
|
||||
#define STORE(m,r) _mm_storeu_si128((__m128i*)(m), (__m128i) (r))
|
||||
#define ROTV1(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(0,3,2,1))
|
||||
#define ROTV2(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(1,0,3,2))
|
||||
#define ROTV3(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(2,1,0,3))
|
||||
#define ROTW7(x) (vec)(_mm_slli_epi32((__m128i)x, 7) ^ _mm_srli_epi32((__m128i)x,25))
|
||||
#define ROTW12(x) (vec)(_mm_slli_epi32((__m128i)x,12) ^ _mm_srli_epi32((__m128i)x,20))
|
||||
#if __SSSE3__
|
||||
#include <tmmintrin.h>
|
||||
#define ROTW8(x) (vec)_mm_shuffle_epi8((__m128i)x,_mm_set_epi8(14,13,12,15,10,9,8,11,6,5,4,7,2,1,0,3))
|
||||
#define ROTW16(x) (vec)_mm_shuffle_epi8((__m128i)x,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2))
|
||||
#else
|
||||
#define ROTW8(x) (vec)(_mm_slli_epi32((__m128i)x, 8) ^ _mm_srli_epi32((__m128i)x,24))
|
||||
#define ROTW16(x) (vec)(_mm_slli_epi32((__m128i)x,16) ^ _mm_srli_epi32((__m128i)x,16))
|
||||
#endif
|
||||
#else
|
||||
#error -- Implementation supports only machines with neon or SSE2
|
||||
#endif
|
||||
|
||||
#ifndef REVV_BE
|
||||
#define REVV_BE(x) (x)
|
||||
#endif
|
||||
|
||||
#ifndef REVW_BE
|
||||
#define REVW_BE(x) (x)
|
||||
#endif
|
||||
|
||||
#define BPI (VBPI + GPR_TOO) /* Blocks computed per loop iteration */
|
||||
|
||||
#define DQROUND_VECTORS(a,b,c,d) \
|
||||
a += b; d ^= a; d = ROTW16(d); \
|
||||
c += d; b ^= c; b = ROTW12(b); \
|
||||
a += b; d ^= a; d = ROTW8(d); \
|
||||
c += d; b ^= c; b = ROTW7(b); \
|
||||
b = ROTV1(b); c = ROTV2(c); d = ROTV3(d); \
|
||||
a += b; d ^= a; d = ROTW16(d); \
|
||||
c += d; b ^= c; b = ROTW12(b); \
|
||||
a += b; d ^= a; d = ROTW8(d); \
|
||||
c += d; b ^= c; b = ROTW7(b); \
|
||||
b = ROTV3(b); c = ROTV2(c); d = ROTV1(d);
|
||||
|
||||
#define QROUND_WORDS(a,b,c,d) \
|
||||
a = a+b; d ^= a; d = d<<16 | d>>16; \
|
||||
c = c+d; b ^= c; b = b<<12 | b>>20; \
|
||||
a = a+b; d ^= a; d = d<< 8 | d>>24; \
|
||||
c = c+d; b ^= c; b = b<< 7 | b>>25;
|
||||
|
||||
#define WRITE_XOR(in, op, d, v0, v1, v2, v3) \
|
||||
STORE(op + d + 0, LOAD(in + d + 0) ^ REVV_BE(v0)); \
|
||||
STORE(op + d + 4, LOAD(in + d + 4) ^ REVV_BE(v1)); \
|
||||
STORE(op + d + 8, LOAD(in + d + 8) ^ REVV_BE(v2)); \
|
||||
STORE(op + d +12, LOAD(in + d +12) ^ REVV_BE(v3));
|
||||
|
||||
void
|
||||
ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inlen,
|
||||
const unsigned char key[32], const unsigned char nonce[12],
|
||||
uint32_t counter)
|
||||
{
|
||||
unsigned iters, i, *op=(unsigned *)out, *ip=(unsigned *)in, *kp;
|
||||
#if defined(__ARM_NEON__)
|
||||
unsigned *np;
|
||||
#endif
|
||||
vec s0, s1, s2, s3;
|
||||
#if !defined(__ARM_NEON__) && !defined(__SSE2__)
|
||||
__attribute__ ((aligned (16))) unsigned key[8], nonce[4];
|
||||
#endif
|
||||
__attribute__ ((aligned (16))) unsigned chacha_const[] =
|
||||
{0x61707865,0x3320646E,0x79622D32,0x6B206574};
|
||||
#if defined(__ARM_NEON__) || defined(__SSE2__)
|
||||
kp = (unsigned *)key;
|
||||
#else
|
||||
((vec *)key)[0] = REVV_BE(((vec *)key)[0]);
|
||||
((vec *)key)[1] = REVV_BE(((vec *)key)[1]);
|
||||
((unsigned *)nonce)[0] = REVW_BE(((unsigned *)nonce)[0]);
|
||||
((unsigned *)nonce)[1] = REVW_BE(((unsigned *)nonce)[1]);
|
||||
((unsigned *)nonce)[2] = REVW_BE(((unsigned *)nonce)[2]);
|
||||
((unsigned *)nonce)[3] = REVW_BE(((unsigned *)nonce)[3]);
|
||||
kp = (unsigned *)key;
|
||||
np = (unsigned *)nonce;
|
||||
#endif
|
||||
#if defined(__ARM_NEON__)
|
||||
np = (unsigned*) nonce;
|
||||
#endif
|
||||
s0 = LOAD(chacha_const);
|
||||
s1 = LOAD(&((vec*)kp)[0]);
|
||||
s2 = LOAD(&((vec*)kp)[1]);
|
||||
s3 = (vec) {
|
||||
counter,
|
||||
((uint32_t*)nonce)[0],
|
||||
((uint32_t*)nonce)[1],
|
||||
((uint32_t*)nonce)[2]
|
||||
};
|
||||
|
||||
for (iters = 0; iters < inlen/(BPI*64); iters++) {
|
||||
#if GPR_TOO
|
||||
register unsigned x0, x1, x2, x3, x4, x5, x6, x7, x8,
|
||||
x9, x10, x11, x12, x13, x14, x15;
|
||||
#endif
|
||||
#if VBPI > 2
|
||||
vec v8,v9,v10,v11;
|
||||
#endif
|
||||
#if VBPI > 3
|
||||
vec v12,v13,v14,v15;
|
||||
#endif
|
||||
|
||||
vec v0,v1,v2,v3,v4,v5,v6,v7;
|
||||
v4 = v0 = s0; v5 = v1 = s1; v6 = v2 = s2; v3 = s3;
|
||||
v7 = v3 + ONE;
|
||||
#if VBPI > 2
|
||||
v8 = v4; v9 = v5; v10 = v6;
|
||||
v11 = v7 + ONE;
|
||||
#endif
|
||||
#if VBPI > 3
|
||||
v12 = v8; v13 = v9; v14 = v10;
|
||||
v15 = v11 + ONE;
|
||||
#endif
|
||||
#if GPR_TOO
|
||||
x0 = chacha_const[0]; x1 = chacha_const[1];
|
||||
x2 = chacha_const[2]; x3 = chacha_const[3];
|
||||
x4 = kp[0]; x5 = kp[1]; x6 = kp[2]; x7 = kp[3];
|
||||
x8 = kp[4]; x9 = kp[5]; x10 = kp[6]; x11 = kp[7];
|
||||
x12 = counter+BPI*iters+(BPI-1); x13 = np[0];
|
||||
x14 = np[1]; x15 = np[2];
|
||||
#endif
|
||||
for (i = CHACHA_RNDS/2; i; i--) {
|
||||
DQROUND_VECTORS(v0,v1,v2,v3)
|
||||
DQROUND_VECTORS(v4,v5,v6,v7)
|
||||
#if VBPI > 2
|
||||
DQROUND_VECTORS(v8,v9,v10,v11)
|
||||
#endif
|
||||
#if VBPI > 3
|
||||
DQROUND_VECTORS(v12,v13,v14,v15)
|
||||
#endif
|
||||
#if GPR_TOO
|
||||
QROUND_WORDS( x0, x4, x8,x12)
|
||||
QROUND_WORDS( x1, x5, x9,x13)
|
||||
QROUND_WORDS( x2, x6,x10,x14)
|
||||
QROUND_WORDS( x3, x7,x11,x15)
|
||||
QROUND_WORDS( x0, x5,x10,x15)
|
||||
QROUND_WORDS( x1, x6,x11,x12)
|
||||
QROUND_WORDS( x2, x7, x8,x13)
|
||||
QROUND_WORDS( x3, x4, x9,x14)
|
||||
#endif
|
||||
}
|
||||
|
||||
WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
|
||||
s3 += ONE;
|
||||
WRITE_XOR(ip, op, 16, v4+s0, v5+s1, v6+s2, v7+s3)
|
||||
s3 += ONE;
|
||||
#if VBPI > 2
|
||||
WRITE_XOR(ip, op, 32, v8+s0, v9+s1, v10+s2, v11+s3)
|
||||
s3 += ONE;
|
||||
#endif
|
||||
#if VBPI > 3
|
||||
WRITE_XOR(ip, op, 48, v12+s0, v13+s1, v14+s2, v15+s3)
|
||||
s3 += ONE;
|
||||
#endif
|
||||
ip += VBPI*16;
|
||||
op += VBPI*16;
|
||||
#if GPR_TOO
|
||||
op[0] = REVW_BE(REVW_BE(ip[0]) ^ (x0 + chacha_const[0]));
|
||||
op[1] = REVW_BE(REVW_BE(ip[1]) ^ (x1 + chacha_const[1]));
|
||||
op[2] = REVW_BE(REVW_BE(ip[2]) ^ (x2 + chacha_const[2]));
|
||||
op[3] = REVW_BE(REVW_BE(ip[3]) ^ (x3 + chacha_const[3]));
|
||||
op[4] = REVW_BE(REVW_BE(ip[4]) ^ (x4 + kp[0]));
|
||||
op[5] = REVW_BE(REVW_BE(ip[5]) ^ (x5 + kp[1]));
|
||||
op[6] = REVW_BE(REVW_BE(ip[6]) ^ (x6 + kp[2]));
|
||||
op[7] = REVW_BE(REVW_BE(ip[7]) ^ (x7 + kp[3]));
|
||||
op[8] = REVW_BE(REVW_BE(ip[8]) ^ (x8 + kp[4]));
|
||||
op[9] = REVW_BE(REVW_BE(ip[9]) ^ (x9 + kp[5]));
|
||||
op[10] = REVW_BE(REVW_BE(ip[10]) ^ (x10 + kp[6]));
|
||||
op[11] = REVW_BE(REVW_BE(ip[11]) ^ (x11 + kp[7]));
|
||||
op[12] = REVW_BE(REVW_BE(ip[12]) ^ (x12 + counter+BPI*iters+(BPI-1)));
|
||||
op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13 + np[0]));
|
||||
op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[1]));
|
||||
op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[2]));
|
||||
s3 += ONE;
|
||||
ip += 16;
|
||||
op += 16;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (iters = inlen%(BPI*64)/64; iters != 0; iters--) {
|
||||
vec v0 = s0, v1 = s1, v2 = s2, v3 = s3;
|
||||
for (i = CHACHA_RNDS/2; i; i--) {
|
||||
DQROUND_VECTORS(v0,v1,v2,v3);
|
||||
}
|
||||
WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
|
||||
s3 += ONE;
|
||||
ip += 16;
|
||||
op += 16;
|
||||
}
|
||||
|
||||
inlen = inlen % 64;
|
||||
if (inlen) {
|
||||
__attribute__ ((aligned (16))) vec buf[4];
|
||||
vec v0,v1,v2,v3;
|
||||
v0 = s0; v1 = s1; v2 = s2; v3 = s3;
|
||||
for (i = CHACHA_RNDS/2; i; i--) {
|
||||
DQROUND_VECTORS(v0,v1,v2,v3);
|
||||
}
|
||||
|
||||
if (inlen >= 16) {
|
||||
STORE(op + 0, LOAD(ip + 0) ^ REVV_BE(v0 + s0));
|
||||
if (inlen >= 32) {
|
||||
STORE(op + 4, LOAD(ip + 4) ^ REVV_BE(v1 + s1));
|
||||
if (inlen >= 48) {
|
||||
STORE(op + 8, LOAD(ip + 8) ^ REVV_BE(v2 + s2));
|
||||
buf[3] = REVV_BE(v3 + s3);
|
||||
} else {
|
||||
buf[2] = REVV_BE(v2 + s2);
|
||||
}
|
||||
} else {
|
||||
buf[1] = REVV_BE(v1 + s1);
|
||||
}
|
||||
} else {
|
||||
buf[0] = REVV_BE(v0 + s0);
|
||||
}
|
||||
|
||||
for (i=inlen & ~15; i<inlen; i++) {
|
||||
((char *)op)[i] = ((char *)ip)[i] ^ ((char *)buf)[i];
|
||||
}
|
||||
}
|
||||
}
|
175
security/nss/lib/freebl/chacha20poly1305.c
Normal file
175
security/nss/lib/freebl/chacha20poly1305.c
Normal file
@ -0,0 +1,175 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secerr.h"
|
||||
#include "blapit.h"
|
||||
#include "poly1305.h"
|
||||
#include "chacha20.h"
|
||||
#include "chacha20poly1305.h"
|
||||
|
||||
/* Poly1305Do writes the Poly1305 authenticator of the given additional data
|
||||
* and ciphertext to |out|. */
|
||||
static void
|
||||
Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
|
||||
const unsigned char *ciphertext, unsigned int ciphertextLen,
|
||||
const unsigned char key[32])
|
||||
{
|
||||
poly1305_state state;
|
||||
unsigned int j;
|
||||
unsigned char lengthBytes[8];
|
||||
static const unsigned char zeros[15];
|
||||
unsigned int i;
|
||||
|
||||
Poly1305Init(&state, key);
|
||||
Poly1305Update(&state, ad, adLen);
|
||||
if (adLen % 16 > 0) {
|
||||
Poly1305Update(&state, zeros, 16 - adLen % 16);
|
||||
}
|
||||
Poly1305Update(&state, ciphertext, ciphertextLen);
|
||||
if (ciphertextLen % 16 > 0) {
|
||||
Poly1305Update(&state, zeros, 16 - ciphertextLen % 16);
|
||||
}
|
||||
j = adLen;
|
||||
for (i = 0; i < sizeof(lengthBytes); i++) {
|
||||
lengthBytes[i] = j;
|
||||
j >>= 8;
|
||||
}
|
||||
Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
|
||||
j = ciphertextLen;
|
||||
for (i = 0; i < sizeof(lengthBytes); i++) {
|
||||
lengthBytes[i] = j;
|
||||
j >>= 8;
|
||||
}
|
||||
Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
|
||||
Poly1305Finish(&state, out);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key, unsigned int keyLen,
|
||||
unsigned int tagLen)
|
||||
{
|
||||
if (keyLen != 32) {
|
||||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
return SECFailure;
|
||||
}
|
||||
if (tagLen == 0 || tagLen > 16) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memcpy(ctx->key, key, sizeof(ctx->key));
|
||||
ctx->tagLen = tagLen;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
ChaCha20Poly1305Context *
|
||||
ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
|
||||
unsigned int tagLen)
|
||||
{
|
||||
ChaCha20Poly1305Context *ctx;
|
||||
|
||||
ctx = PORT_New(ChaCha20Poly1305Context);
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ChaCha20Poly1305_InitContext(ctx, key, keyLen, tagLen) != SECSuccess) {
|
||||
PORT_Free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void
|
||||
ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
|
||||
{
|
||||
PORT_Memset(ctx, 0, sizeof(*ctx));
|
||||
if (freeit) {
|
||||
PORT_Free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
unsigned char block[64];
|
||||
unsigned char tag[16];
|
||||
|
||||
if (nonceLen != 12) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
*outputLen = inputLen + ctx->tagLen;
|
||||
if (maxOutputLen < *outputLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memset(block, 0, sizeof(block));
|
||||
// Generate a block of keystream. The first 32 bytes will be the poly1305
|
||||
// key. The remainder of the block is discarded.
|
||||
ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
|
||||
ChaCha20XOR(output, input, inputLen, ctx->key, nonce, 1);
|
||||
|
||||
Poly1305Do(tag, ad, adLen, output, inputLen, block);
|
||||
PORT_Memcpy(output + inputLen, tag, ctx->tagLen);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
unsigned char block[64];
|
||||
unsigned char tag[16];
|
||||
unsigned int ciphertextLen;
|
||||
|
||||
if (nonceLen != 12) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
if (inputLen < ctx->tagLen) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
ciphertextLen = inputLen - ctx->tagLen;
|
||||
*outputLen = ciphertextLen;
|
||||
if (maxOutputLen < *outputLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memset(block, 0, sizeof(block));
|
||||
// Generate a block of keystream. The first 32 bytes will be the poly1305
|
||||
// key. The remainder of the block is discarded.
|
||||
ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
|
||||
Poly1305Do(tag, ad, adLen, input, ciphertextLen, block);
|
||||
if (NSS_SecureMemcmp(tag, &input[ciphertextLen], ctx->tagLen) != 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ChaCha20XOR(output, input, ciphertextLen, ctx->key, nonce, 1);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
15
security/nss/lib/freebl/chacha20poly1305.h
Normal file
15
security/nss/lib/freebl/chacha20poly1305.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _CHACHA20_POLY1305_H_
|
||||
#define _CHACHA20_POLY1305_H_ 1
|
||||
|
||||
/* ChaCha20Poly1305ContextStr saves the key and tag length for a
|
||||
* ChaCha20+Poly1305 AEAD operation. */
|
||||
struct ChaCha20Poly1305ContextStr {
|
||||
unsigned char key[32];
|
||||
unsigned char tagLen;
|
||||
};
|
||||
|
||||
#endif /* _CHACHA20_POLY1305_H_ */
|
@ -13,6 +13,13 @@
|
||||
#include <stddef.h> /* for ptrdiff_t */
|
||||
/* #define USE_INDEXING 1 */
|
||||
|
||||
/* Some processors automatically fix up unaligned memory access, so they can
|
||||
* read or write a HALF (4 bytes) at a time whether the address is 4-byte
|
||||
* aligned or not. */
|
||||
#if defined(NSS_X86_OR_X64)
|
||||
#define HAVE_UNALIGNED_ACCESS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The tables below are the 8 sbox functions, with the 6-bit input permutation
|
||||
* and the 32-bit output permutation pre-computed.
|
||||
@ -421,11 +428,13 @@ DES_MakeSchedule( HALF * ks, const BYTE * key, DESDirection direction)
|
||||
int delta;
|
||||
unsigned int ls;
|
||||
|
||||
#if defined(NSS_X86_OR_X64)
|
||||
#if defined(HAVE_UNALIGNED_ACCESS)
|
||||
left = HALFPTR(key)[0];
|
||||
right = HALFPTR(key)[1];
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
BYTESWAP(left, temp);
|
||||
BYTESWAP(right, temp);
|
||||
#endif
|
||||
#else
|
||||
if (((ptrdiff_t)key & 0x03) == 0) {
|
||||
left = HALFPTR(key)[0];
|
||||
@ -572,11 +581,13 @@ DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf)
|
||||
register HALF left, right;
|
||||
register HALF temp;
|
||||
|
||||
#if defined(NSS_X86_OR_X64)
|
||||
#if defined(HAVE_UNALIGNED_ACCESS)
|
||||
left = HALFPTR(inbuf)[0];
|
||||
right = HALFPTR(inbuf)[1];
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
BYTESWAP(left, temp);
|
||||
BYTESWAP(right, temp);
|
||||
#endif
|
||||
#else
|
||||
if (((ptrdiff_t)inbuf & 0x03) == 0) {
|
||||
left = HALFPTR(inbuf)[0];
|
||||
@ -643,9 +654,11 @@ DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf)
|
||||
|
||||
FP(left, right, temp);
|
||||
|
||||
#if defined(NSS_X86_OR_X64)
|
||||
#if defined(HAVE_UNALIGNED_ACCESS)
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
BYTESWAP(left, temp);
|
||||
BYTESWAP(right, temp);
|
||||
#endif
|
||||
HALFPTR(outbuf)[0] = left;
|
||||
HALFPTR(outbuf)[1] = right;
|
||||
#else
|
||||
|
@ -22,28 +22,8 @@
|
||||
#define COPY8B(to, from, ptr) \
|
||||
HALFPTR(to)[0] = HALFPTR(from)[0]; \
|
||||
HALFPTR(to)[1] = HALFPTR(from)[1];
|
||||
#elif defined(USE_MEMCPY)
|
||||
#define COPY8B(to, from, ptr) memcpy(to, from, 8)
|
||||
#else
|
||||
#define COPY8B(to, from, ptr) \
|
||||
if (((ptrdiff_t)(ptr) & 0x3) == 0) { \
|
||||
HALFPTR(to)[0] = HALFPTR(from)[0]; \
|
||||
HALFPTR(to)[1] = HALFPTR(from)[1]; \
|
||||
} else if (((ptrdiff_t)(ptr) & 0x1) == 0) { \
|
||||
SHORTPTR(to)[0] = SHORTPTR(from)[0]; \
|
||||
SHORTPTR(to)[1] = SHORTPTR(from)[1]; \
|
||||
SHORTPTR(to)[2] = SHORTPTR(from)[2]; \
|
||||
SHORTPTR(to)[3] = SHORTPTR(from)[3]; \
|
||||
} else { \
|
||||
BYTEPTR(to)[0] = BYTEPTR(from)[0]; \
|
||||
BYTEPTR(to)[1] = BYTEPTR(from)[1]; \
|
||||
BYTEPTR(to)[2] = BYTEPTR(from)[2]; \
|
||||
BYTEPTR(to)[3] = BYTEPTR(from)[3]; \
|
||||
BYTEPTR(to)[4] = BYTEPTR(from)[4]; \
|
||||
BYTEPTR(to)[5] = BYTEPTR(from)[5]; \
|
||||
BYTEPTR(to)[6] = BYTEPTR(from)[6]; \
|
||||
BYTEPTR(to)[7] = BYTEPTR(from)[7]; \
|
||||
}
|
||||
#define COPY8B(to, from, ptr) memcpy(to, from, 8)
|
||||
#endif
|
||||
#define COPY8BTOHALF(to, from) COPY8B(to, from, from)
|
||||
#define COPY8BFROMHALF(to, from) COPY8B(to, from, to)
|
||||
|
@ -208,7 +208,8 @@ DH_Derive(SECItem *publicValue,
|
||||
unsigned int len = 0;
|
||||
unsigned int nb;
|
||||
unsigned char *secret = NULL;
|
||||
if (!publicValue || !prime || !privateValue || !derivedSecret) {
|
||||
if (!publicValue || !publicValue->len || !prime || !prime->len ||
|
||||
!privateValue || !privateValue->len || !derivedSecret) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
* for SHA-1, SHA-224, and SHA-256 it's 440 bits.
|
||||
* for SHA-384 and SHA-512 it's 888 bits */
|
||||
#define PRNG_SEEDLEN (440/PR_BITS_PER_BYTE)
|
||||
static const PRInt64 PRNG_MAX_ADDITIONAL_BYTES = LL_INIT(0x1, 0x0);
|
||||
#define PRNG_MAX_ADDITIONAL_BYTES PR_INT64(0x100000000)
|
||||
/* 2^35 bits or 2^32 bytes */
|
||||
#define PRNG_MAX_REQUEST_SIZE 0x10000 /* 2^19 bits or 2^16 bytes */
|
||||
#define PRNG_ADDITONAL_DATA_CACHE_SIZE (8*1024) /* must be less than
|
||||
@ -96,7 +96,8 @@ struct RNGContextStr {
|
||||
* RNG_RandomUpdate. */
|
||||
PRUint8 additionalDataCache[PRNG_ADDITONAL_DATA_CACHE_SIZE];
|
||||
PRUint32 additionalAvail;
|
||||
PRBool isValid; /* false if RNG reaches an invalid state */
|
||||
PRBool isValid; /* false if RNG reaches an invalid state */
|
||||
PRBool isKatTest; /* true if running NIST PRNG KAT tests */
|
||||
};
|
||||
|
||||
typedef struct RNGContextStr RNGContext;
|
||||
@ -149,7 +150,7 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
|
||||
|
||||
|
||||
/*
|
||||
* Hash_DRBG Instantiate NIST SP 800-80 10.1.1.2
|
||||
* Hash_DRBG Instantiate NIST SP 800-90 10.1.1.2
|
||||
*
|
||||
* NOTE: bytes & len are entropy || nonce || personalization_string. In
|
||||
* normal operation, NSS calculates them all together in a single call.
|
||||
@ -157,9 +158,11 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
|
||||
static SECStatus
|
||||
prng_instantiate(RNGContext *rng, const PRUint8 *bytes, unsigned int len)
|
||||
{
|
||||
if (len < PRNG_SEEDLEN) {
|
||||
/* if the seedlen is to small, it's probably because we failed to get
|
||||
* enough random data */
|
||||
if (!rng->isKatTest && len < PRNG_SEEDLEN) {
|
||||
/* If the seedlen is too small, it's probably because we failed to get
|
||||
* enough random data.
|
||||
* This is stricter than NIST SP800-90A requires. Don't enforce it for
|
||||
* tests. */
|
||||
PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
||||
return SECFailure;
|
||||
}
|
||||
@ -272,7 +275,7 @@ prng_reseed_test(RNGContext *rng, const PRUint8 *entropy,
|
||||
|
||||
#define PRNG_ADD_BITS_AND_CARRY(dest, dest_len, add, len, carry) \
|
||||
PRNG_ADD_BITS(dest, dest_len, add, len, carry) \
|
||||
PRNG_ADD_CARRY_ONLY(dest, dest_len - len, carry)
|
||||
PRNG_ADD_CARRY_ONLY(dest, dest_len - len - 1, carry)
|
||||
|
||||
/*
|
||||
* This function expands the internal state of the prng to fulfill any number
|
||||
@ -423,6 +426,7 @@ static PRStatus rng_init(void)
|
||||
}
|
||||
/* the RNG is in a valid state */
|
||||
globalrng->isValid = PR_TRUE;
|
||||
globalrng->isKatTest = PR_FALSE;
|
||||
|
||||
/* fetch one random value so that we can populate rng->oldV for our
|
||||
* continous random number test. */
|
||||
@ -667,6 +671,17 @@ RNG_RNGShutdown(void)
|
||||
* entropy we may have previously collected. */
|
||||
RNGContext testContext;
|
||||
|
||||
SECStatus
|
||||
PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len,
|
||||
const PRUint8 *nonce, unsigned int nonce_len,
|
||||
const PRUint8 *personal_string, unsigned int ps_len)
|
||||
{
|
||||
testContext.isKatTest = PR_TRUE;
|
||||
return PRNGTEST_Instantiate(entropy, entropy_len,
|
||||
nonce, nonce_len,
|
||||
personal_string, ps_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test vector API. Use NIST SP 800-90 general interface so one of the
|
||||
* other NIST SP 800-90 algorithms may be used in the future.
|
||||
|
@ -215,7 +215,8 @@ ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
|
||||
#endif
|
||||
MP_DIGITS(&k) = 0;
|
||||
|
||||
if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
|
||||
if (!ecParams || ecParams->name == ECCurve_noName ||
|
||||
!privKey || !privKeyBytes || privKeyLen <= 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
@ -395,7 +396,7 @@ EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey)
|
||||
int len;
|
||||
unsigned char *privKeyBytes = NULL;
|
||||
|
||||
if (!ecParams) {
|
||||
if (!ecParams || ecParams->name == ECCurve_noName || !privKey) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
@ -437,7 +438,8 @@ EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
|
||||
mp_err err = MP_OKAY;
|
||||
int len;
|
||||
|
||||
if (!ecParams || !publicValue) {
|
||||
if (!ecParams || ecParams->name == ECCurve_noName ||
|
||||
!publicValue || !publicValue->len) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
@ -537,8 +539,9 @@ ECDH_Derive(SECItem *publicValue,
|
||||
int i;
|
||||
#endif
|
||||
|
||||
if (!publicValue || !ecParams || !privateValue ||
|
||||
!derivedSecret) {
|
||||
if (!publicValue || !publicValue->len ||
|
||||
!ecParams || ecParams->name == ECCurve_noName ||
|
||||
!privateValue || !privateValue->len || !derivedSecret) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -78,7 +78,8 @@ LIBOBJS = ecl.o ecl_curve.o ecl_mult.o ecl_gf.o \
|
||||
ecp_aff.o ecp_jac.o ecp_mont.o \
|
||||
ec_naf.o ecp_jm.o \
|
||||
ecp_192.o ecp_224.o ecp_256.o ecp_384.o ecp_521.o \
|
||||
ecp_256_32.o
|
||||
ecp_256_32.o \
|
||||
curve25519_32.o
|
||||
ifeq ($(ECL_USE_FP),1)
|
||||
LIBOBJS+= ecp_fp160.o ecp_fp192.o ecp_fp224.o ecp_fp.o
|
||||
endif
|
||||
@ -131,6 +132,7 @@ ecp_256.o: ecp_256.c $(LIBHDRS)
|
||||
ecp_384.o: ecp_384.c $(LIBHDRS)
|
||||
ecp_521.o: ecp_521.c $(LIBHDRS)
|
||||
ecp_fp.o: ecp_fp.c $(LIBHDRS)
|
||||
curve25519_32.o: curve25519_32.c $(LIBHDRS)
|
||||
ifeq ($(ECL_USE_FP),1)
|
||||
ecp_fp160.o: ecp_fp160.c ecp_fpinc.c $(LIBHDRS)
|
||||
ecp_fp192.o: ecp_fp192.c ecp_fpinc.c $(LIBHDRS)
|
||||
|
393
security/nss/lib/freebl/ecl/curve25519_32.c
Normal file
393
security/nss/lib/freebl/ecl/curve25519_32.c
Normal file
@ -0,0 +1,393 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Derived from public domain code by Matthew Dempsky and D. J. Bernstein.
|
||||
*/
|
||||
|
||||
#include "ecl-priv.h"
|
||||
#include "mpi.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secerr.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
typedef PRUint32 elem[32];
|
||||
|
||||
/*
|
||||
* Add two field elements.
|
||||
* out = a + b
|
||||
*/
|
||||
static void
|
||||
add(elem out, const elem a, const elem b)
|
||||
{
|
||||
PRUint32 j;
|
||||
PRUint32 u = 0;
|
||||
for (j = 0; j < 31; ++j) {
|
||||
u += a[j] + b[j];
|
||||
out[j] = u & 0xFF;
|
||||
u >>= 8;
|
||||
}
|
||||
u += a[31] + b[31];
|
||||
out[31] = u;
|
||||
}
|
||||
|
||||
/*
|
||||
* Subtract two field elements.
|
||||
* out = a - b
|
||||
*/
|
||||
static void
|
||||
sub(elem out, const elem a, const elem b)
|
||||
{
|
||||
PRUint32 j;
|
||||
PRUint32 u;
|
||||
u = 218;
|
||||
for (j = 0; j < 31; ++j) {
|
||||
u += a[j] + 0xFF00 - b[j];
|
||||
out[j] = u & 0xFF;
|
||||
u >>= 8;
|
||||
}
|
||||
u += a[31] - b[31];
|
||||
out[31] = u;
|
||||
}
|
||||
|
||||
/*
|
||||
* "Squeeze" an element after multiplication (and square).
|
||||
*/
|
||||
static void
|
||||
squeeze(elem a)
|
||||
{
|
||||
PRUint32 j;
|
||||
PRUint32 u;
|
||||
u = 0;
|
||||
for (j = 0; j < 31; ++j) {
|
||||
u += a[j];
|
||||
a[j] = u & 0xFF;
|
||||
u >>= 8;
|
||||
}
|
||||
u += a[31];
|
||||
a[31] = u & 0x7F;
|
||||
u = 19 * (u >> 7);
|
||||
for (j = 0; j < 31; ++j) {
|
||||
u += a[j];
|
||||
a[j] = u & 0xFF;
|
||||
u >>= 8;
|
||||
}
|
||||
a[31] += u;
|
||||
}
|
||||
|
||||
static const elem minusp = { 19, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 128 };
|
||||
|
||||
/*
|
||||
* Reduce point a by 2^255-19
|
||||
*/
|
||||
static void
|
||||
reduce(elem a)
|
||||
{
|
||||
elem aorig;
|
||||
PRUint32 j;
|
||||
PRUint32 negative;
|
||||
|
||||
for (j = 0; j < 32; ++j) {
|
||||
aorig[j] = a[j];
|
||||
}
|
||||
add(a, a, minusp);
|
||||
negative = 1 + ~((a[31] >> 7) & 1);
|
||||
for (j = 0; j < 32; ++j) {
|
||||
a[j] ^= negative & (aorig[j] ^ a[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication and squeeze
|
||||
* out = a * b
|
||||
*/
|
||||
static void
|
||||
mult(elem out, const elem a, const elem b)
|
||||
{
|
||||
PRUint32 i;
|
||||
PRUint32 j;
|
||||
PRUint32 u;
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
u = 0;
|
||||
for (j = 0; j <= i; ++j) {
|
||||
u += a[j] * b[i - j];
|
||||
}
|
||||
for (j = i + 1; j < 32; ++j) {
|
||||
u += 38 * a[j] * b[i + 32 - j];
|
||||
}
|
||||
out[i] = u;
|
||||
}
|
||||
squeeze(out);
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication
|
||||
* out = 121665 * a
|
||||
*/
|
||||
static void
|
||||
mult121665(elem out, const elem a)
|
||||
{
|
||||
PRUint32 j;
|
||||
PRUint32 u;
|
||||
|
||||
u = 0;
|
||||
for (j = 0; j < 31; ++j) {
|
||||
u += 121665 * a[j];
|
||||
out[j] = u & 0xFF;
|
||||
u >>= 8;
|
||||
}
|
||||
u += 121665 * a[31];
|
||||
out[31] = u & 0x7F;
|
||||
u = 19 * (u >> 7);
|
||||
for (j = 0; j < 31; ++j) {
|
||||
u += out[j];
|
||||
out[j] = u & 0xFF;
|
||||
u >>= 8;
|
||||
}
|
||||
u += out[j];
|
||||
out[j] = u;
|
||||
}
|
||||
|
||||
/*
|
||||
* Square a and squeeze the result.
|
||||
* out = a * a
|
||||
*/
|
||||
static void
|
||||
square(elem out, const elem a)
|
||||
{
|
||||
PRUint32 i;
|
||||
PRUint32 j;
|
||||
PRUint32 u;
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
u = 0;
|
||||
for (j = 0; j < i - j; ++j) {
|
||||
u += a[j] * a[i - j];
|
||||
}
|
||||
for (j = i + 1; j < i + 32 - j; ++j) {
|
||||
u += 38 * a[j] * a[i + 32 - j];
|
||||
}
|
||||
u *= 2;
|
||||
if ((i & 1) == 0) {
|
||||
u += a[i / 2] * a[i / 2];
|
||||
u += 38 * a[i / 2 + 16] * a[i / 2 + 16];
|
||||
}
|
||||
out[i] = u;
|
||||
}
|
||||
squeeze(out);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constant time swap between r and s depending on b
|
||||
*/
|
||||
static void
|
||||
cswap(PRUint32 p[64], PRUint32 q[64], PRUint32 b)
|
||||
{
|
||||
PRUint32 j;
|
||||
PRUint32 swap = 1 + ~b;
|
||||
|
||||
for (j = 0; j < 64; ++j) {
|
||||
const PRUint32 t = swap & (p[j] ^ q[j]);
|
||||
p[j] ^= t;
|
||||
q[j] ^= t;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Montgomery ladder
|
||||
*/
|
||||
static void
|
||||
monty(elem x_2_out, elem z_2_out,
|
||||
const elem point, const elem scalar)
|
||||
{
|
||||
PRUint32 x_3[64] = { 0 };
|
||||
PRUint32 x_2[64] = { 0 };
|
||||
PRUint32 a0[64];
|
||||
PRUint32 a1[64];
|
||||
PRUint32 b0[64];
|
||||
PRUint32 b1[64];
|
||||
PRUint32 c1[64];
|
||||
PRUint32 r[32];
|
||||
PRUint32 s[32];
|
||||
PRUint32 t[32];
|
||||
PRUint32 u[32];
|
||||
PRUint32 swap = 0;
|
||||
PRUint32 k_t = 0;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < 32; ++j) {
|
||||
x_3[j] = point[j];
|
||||
}
|
||||
x_3[32] = 1;
|
||||
x_2[0] = 1;
|
||||
|
||||
for (j = 254; j >= 0; --j) {
|
||||
k_t = (scalar[j >> 3] >> (j & 7)) & 1;
|
||||
swap ^= k_t;
|
||||
cswap(x_2, x_3, swap);
|
||||
swap = k_t;
|
||||
add(a0, x_2, x_2 + 32);
|
||||
sub(a0 + 32, x_2, x_2 + 32);
|
||||
add(a1, x_3, x_3 + 32);
|
||||
sub(a1 + 32, x_3, x_3 + 32);
|
||||
square(b0, a0);
|
||||
square(b0 + 32, a0 + 32);
|
||||
mult(b1, a1, a0 + 32);
|
||||
mult(b1 + 32, a1 + 32, a0);
|
||||
add(c1, b1, b1 + 32);
|
||||
sub(c1 + 32, b1, b1 + 32);
|
||||
square(r, c1 + 32);
|
||||
sub(s, b0, b0 + 32);
|
||||
mult121665(t, s);
|
||||
add(u, t, b0);
|
||||
mult(x_2, b0, b0 + 32);
|
||||
mult(x_2 + 32, s, u);
|
||||
square(x_3, c1);
|
||||
mult(x_3 + 32, r, point);
|
||||
}
|
||||
|
||||
cswap(x_2, x_3, swap);
|
||||
for (j = 0; j < 32; ++j) {
|
||||
x_2_out[j] = x_2[j];
|
||||
}
|
||||
for (j = 0; j < 32; ++j) {
|
||||
z_2_out[j] = x_2[j + 32];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recip(elem out, const elem z)
|
||||
{
|
||||
elem z2;
|
||||
elem z9;
|
||||
elem z11;
|
||||
elem z2_5_0;
|
||||
elem z2_10_0;
|
||||
elem z2_20_0;
|
||||
elem z2_50_0;
|
||||
elem z2_100_0;
|
||||
elem t0;
|
||||
elem t1;
|
||||
int i;
|
||||
|
||||
/* 2 */ square(z2, z);
|
||||
/* 4 */ square(t1, z2);
|
||||
/* 8 */ square(t0, t1);
|
||||
/* 9 */ mult(z9, t0, z);
|
||||
/* 11 */ mult(z11, z9, z2);
|
||||
/* 22 */ square(t0, z11);
|
||||
/* 2^5 - 2^0 = 31 */ mult(z2_5_0, t0, z9);
|
||||
|
||||
/* 2^6 - 2^1 */ square(t0, z2_5_0);
|
||||
/* 2^7 - 2^2 */ square(t1, t0);
|
||||
/* 2^8 - 2^3 */ square(t0, t1);
|
||||
/* 2^9 - 2^4 */ square(t1, t0);
|
||||
/* 2^10 - 2^5 */ square(t0, t1);
|
||||
/* 2^10 - 2^0 */ mult(z2_10_0, t0, z2_5_0);
|
||||
|
||||
/* 2^11 - 2^1 */ square(t0, z2_10_0);
|
||||
/* 2^12 - 2^2 */ square(t1, t0);
|
||||
/* 2^20 - 2^10 */
|
||||
for (i = 2; i < 10; i += 2) {
|
||||
square(t0, t1);
|
||||
square(t1, t0);
|
||||
}
|
||||
/* 2^20 - 2^0 */ mult(z2_20_0, t1, z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ square(t0, z2_20_0);
|
||||
/* 2^22 - 2^2 */ square(t1, t0);
|
||||
/* 2^40 - 2^20 */
|
||||
for (i = 2; i < 20; i += 2) {
|
||||
square(t0, t1);
|
||||
square(t1, t0);
|
||||
}
|
||||
/* 2^40 - 2^0 */ mult(t0, t1, z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ square(t1, t0);
|
||||
/* 2^42 - 2^2 */ square(t0, t1);
|
||||
/* 2^50 - 2^10 */
|
||||
for (i = 2; i < 10; i += 2) {
|
||||
square(t1, t0);
|
||||
square(t0, t1);
|
||||
}
|
||||
/* 2^50 - 2^0 */ mult(z2_50_0, t0, z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ square(t0, z2_50_0);
|
||||
/* 2^52 - 2^2 */ square(t1, t0);
|
||||
/* 2^100 - 2^50 */
|
||||
for (i = 2; i < 50; i += 2) {
|
||||
square(t0, t1);
|
||||
square(t1, t0);
|
||||
}
|
||||
/* 2^100 - 2^0 */ mult(z2_100_0, t1, z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ square(t1, z2_100_0);
|
||||
/* 2^102 - 2^2 */ square(t0, t1);
|
||||
/* 2^200 - 2^100 */
|
||||
for (i = 2; i < 100; i += 2) {
|
||||
square(t1, t0);
|
||||
square(t0, t1);
|
||||
}
|
||||
/* 2^200 - 2^0 */ mult(t1, t0, z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ square(t0, t1);
|
||||
/* 2^202 - 2^2 */ square(t1, t0);
|
||||
/* 2^250 - 2^50 */
|
||||
for (i = 2; i < 50; i += 2) {
|
||||
square(t0, t1);
|
||||
square(t1, t0);
|
||||
}
|
||||
/* 2^250 - 2^0 */ mult(t0, t1, z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ square(t1, t0);
|
||||
/* 2^252 - 2^2 */ square(t0, t1);
|
||||
/* 2^253 - 2^3 */ square(t1, t0);
|
||||
/* 2^254 - 2^4 */ square(t0, t1);
|
||||
/* 2^255 - 2^5 */ square(t1, t0);
|
||||
/* 2^255 - 21 */ mult(out, t1, z11);
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes q = Curve25519(p, s)
|
||||
*/
|
||||
SECStatus
|
||||
ec_Curve25519_mul(PRUint8 *q, const PRUint8 *s, const PRUint8 *p)
|
||||
{
|
||||
elem point = { 0 };
|
||||
elem x_2 = { 0 };
|
||||
elem z_2 = { 0 };
|
||||
elem X = { 0 };
|
||||
elem scalar = { 0 };
|
||||
PRUint32 i;
|
||||
|
||||
/* read and mask scalar */
|
||||
for (i = 0; i < 32; ++i) {
|
||||
scalar[i] = s[i];
|
||||
}
|
||||
scalar[0] &= 0xF8;
|
||||
scalar[31] &= 0x7F;
|
||||
scalar[31] |= 64;
|
||||
|
||||
/* read and mask point */
|
||||
for (i = 0; i < 32; ++i) {
|
||||
point[i] = p[i];
|
||||
}
|
||||
point[31] &= 0x7F;
|
||||
|
||||
monty(x_2, z_2, point, scalar);
|
||||
recip(z_2, z_2);
|
||||
mult(X, x_2, z_2);
|
||||
reduce(X);
|
||||
for (i = 0; i < 32; ++i) {
|
||||
q[i] = X[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -120,8 +120,8 @@ ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
|
||||
if (((r2b == 0xffffffff) && (r2a == 0xffffffff)
|
||||
&& (r1b == 0xffffffff) ) &&
|
||||
((r1a == 0xffffffff) ||
|
||||
(r1a == 0xfffffffe) && (r0a == 0xffffffff) &&
|
||||
(r0b == 0xffffffff)) ) {
|
||||
((r1a == 0xfffffffe) && (r0a == 0xffffffff) &&
|
||||
(r0b == 0xffffffff))) ) {
|
||||
/* do a quick subtract */
|
||||
carry = 0;
|
||||
MP_ADD_CARRY(r0a, 1, r0a, carry);
|
||||
|
@ -22,7 +22,7 @@ ec_GFp_nistp224_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
|
||||
mp_digit carry;
|
||||
#ifdef ECL_THIRTY_TWO_BIT
|
||||
mp_digit a6a = 0, a6b = 0,
|
||||
a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
|
||||
a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3b = 0;
|
||||
mp_digit r0a, r0b, r1a, r1b, r2a, r2b, r3a;
|
||||
#else
|
||||
mp_digit a6 = 0, a5 = 0, a4 = 0, a3b = 0, a5a = 0;
|
||||
|
@ -7,15 +7,15 @@
|
||||
/* Copyright(c) 2013, Intel Corp. */
|
||||
/******************************************************************************/
|
||||
/* Reference: */
|
||||
/* [1] Shay Gueron, Michael E. Kounavis: Intel® Carry-Less Multiplication */
|
||||
/* [1] Shay Gueron, Michael E. Kounavis: Intel(R) Carry-Less Multiplication */
|
||||
/* Instruction and its Usage for Computing the GCM Mode (Rev. 2.01) */
|
||||
/* http://software.intel.com/sites/default/files/article/165685/clmul-wp-r*/
|
||||
/*ev-2.01-2012-09-21.pdf */
|
||||
/* [2] S. Gueron, M. E. Kounavis: Efficient Implementation of the Galois */
|
||||
/* Counter Mode Using a Carry-less Multiplier and a Fast Reduction */
|
||||
/* Algorithm. Information Processing Letters 110: 549–553 (2010). */
|
||||
/* [3] S. Gueron: AES Performance on the 2nd Generation Intel® Core™ Processor*/
|
||||
/* Family (to be posted) (2012). */
|
||||
/* Algorithm. Information Processing Letters 110: 549-553 (2010). */
|
||||
/* [3] S. Gueron: AES Performance on the 2nd Generation Intel(R) Core(TM) */
|
||||
/* Processor Family (to be posted) (2012). */
|
||||
/* [4] S. Gueron: Fast GHASH computations for speeding up AES-GCM (to be */
|
||||
/* published) (2012). */
|
||||
|
||||
@ -41,9 +41,9 @@ SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm, unsigned char *
|
||||
const unsigned char *inbuf, unsigned int inlen,
|
||||
unsigned int blocksize);
|
||||
|
||||
/* Prorotypes of functions in the assembler file for fast AES-GCM, using
|
||||
/* Prototypes of functions in the assembler file for fast AES-GCM, using
|
||||
Intel AES-NI and CLMUL-NI, as described in [1]
|
||||
[1] Shay Gueron, Michael E. Kounavis: Intel® Carry-Less Multiplication
|
||||
[1] Shay Gueron, Michael E. Kounavis: Intel(R) Carry-Less Multiplication
|
||||
Instruction and its Usage for Computing the GCM Mode */
|
||||
|
||||
/* Prepares the constants used in the aggregated reduction method */
|
||||
|
@ -286,9 +286,17 @@ static const struct FREEBLVectorStr vector =
|
||||
|
||||
EC_FillParams,
|
||||
EC_DecodeParams,
|
||||
EC_CopyParams
|
||||
EC_CopyParams,
|
||||
|
||||
/* End of Version 3.017 */
|
||||
|
||||
ChaCha20Poly1305_InitContext,
|
||||
ChaCha20Poly1305_CreateContext,
|
||||
ChaCha20Poly1305_DestroyContext,
|
||||
ChaCha20Poly1305_Seal,
|
||||
ChaCha20Poly1305_Open
|
||||
|
||||
/* End of Version 3.018 */
|
||||
};
|
||||
|
||||
const FREEBLVector *
|
||||
|
@ -2128,3 +2128,59 @@ SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
|
||||
return (vector->p_EC_CopyParams)(arena, dstParams, srcParams);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key, unsigned int keyLen,
|
||||
unsigned int tagLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_ChaCha20Poly1305_InitContext)(ctx, key, keyLen, tagLen);
|
||||
}
|
||||
|
||||
ChaCha20Poly1305Context *
|
||||
ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
|
||||
unsigned int tagLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_ChaCha20Poly1305_CreateContext)(key, keyLen, tagLen);
|
||||
}
|
||||
|
||||
void
|
||||
ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_ChaCha20Poly1305_DestroyContext)(ctx, freeit);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_ChaCha20Poly1305_Seal)(
|
||||
ctx, output, outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_ChaCha20Poly1305_Open)(
|
||||
ctx, output, outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "blapi.h"
|
||||
|
||||
#define FREEBL_VERSION 0x0311
|
||||
#define FREEBL_VERSION 0x0312
|
||||
|
||||
struct FREEBLVectorStr {
|
||||
|
||||
@ -707,6 +707,33 @@ struct FREEBLVectorStr {
|
||||
|
||||
/* Version 3.017 came to here */
|
||||
|
||||
SECStatus (* p_ChaCha20Poly1305_InitContext)(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
unsigned int tagLen);
|
||||
|
||||
ChaCha20Poly1305Context *(* p_ChaCha20Poly1305_CreateContext)(
|
||||
const unsigned char *key, unsigned int keyLen, unsigned int tagLen);
|
||||
|
||||
void (* p_ChaCha20Poly1305_DestroyContext)(ChaCha20Poly1305Context *ctx,
|
||||
PRBool freeit);
|
||||
|
||||
SECStatus (* p_ChaCha20Poly1305_Seal)(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
SECStatus (* p_ChaCha20Poly1305_Open)(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
/* Version 3.018 came to here */
|
||||
|
||||
/* Add new function pointers at the end of this struct and bump
|
||||
* FREEBL_VERSION at the beginning of this file. */
|
||||
};
|
||||
|
@ -56,6 +56,7 @@ EXPORTS = \
|
||||
PRIVATE_EXPORTS = \
|
||||
alghmac.h \
|
||||
blapi.h \
|
||||
chacha20poly1305.h \
|
||||
hmacct.h \
|
||||
secmpi.h \
|
||||
secrng.h \
|
||||
@ -73,7 +74,7 @@ ifndef NSS_DISABLE_ECC
|
||||
ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \
|
||||
ecp_aff.c ecp_jac.c ecp_mont.c \
|
||||
ec_naf.c ecp_jm.c ecp_256.c ecp_384.c ecp_521.c \
|
||||
ecp_256_32.c
|
||||
ecp_256_32.c curve25519_32.c
|
||||
ifdef NSS_ECC_MORE_THAN_SUITE_B
|
||||
ECL_SRCS += ec2_aff.c ec2_mont.c ec2_proj.c \
|
||||
ec2_163.c ec2_193.c ec2_233.c \
|
||||
@ -101,6 +102,7 @@ CSRCS = \
|
||||
desblapi.c \
|
||||
des.c \
|
||||
drbg.c \
|
||||
chacha20poly1305.c \
|
||||
cts.c \
|
||||
ctr.c \
|
||||
gcm.c \
|
||||
|
@ -2104,7 +2104,10 @@ mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
|
||||
}
|
||||
}
|
||||
if (res >= 0) {
|
||||
while (MP_SIGN(c) != MP_ZPOS) {
|
||||
if (mp_cmp_mag(c, (mp_int *)p) >= 0) {
|
||||
MP_CHECKOK(mp_div(c, p, NULL, c));
|
||||
}
|
||||
if (MP_SIGN(c) != MP_ZPOS) {
|
||||
MP_CHECKOK( mp_add(c, p, c) );
|
||||
}
|
||||
res = k;
|
||||
@ -4190,6 +4193,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
||||
|
||||
MP_SIGN(rem) = ZPOS;
|
||||
MP_SIGN(div) = ZPOS;
|
||||
MP_SIGN(&part) = ZPOS;
|
||||
|
||||
/* A working temporary for division */
|
||||
MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem)));
|
||||
@ -4197,8 +4201,6 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
||||
/* Normalize to optimize guessing */
|
||||
MP_CHECKOK( s_mp_norm(rem, div, &d) );
|
||||
|
||||
part = *rem;
|
||||
|
||||
/* Perform the division itself...woo! */
|
||||
MP_USED(quot) = MP_ALLOC(quot);
|
||||
|
||||
@ -4207,11 +4209,15 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
||||
while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
|
||||
int i;
|
||||
int unusedRem;
|
||||
int partExtended = 0; /* set to true if we need to extend part */
|
||||
|
||||
unusedRem = MP_USED(rem) - MP_USED(div);
|
||||
MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
|
||||
MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem;
|
||||
MP_USED(&part) = MP_USED(div);
|
||||
|
||||
/* We have now truncated the part of the remainder to the same length as
|
||||
* the divisor. If part is smaller than div, extend part by one digit. */
|
||||
if (s_mp_cmp(&part, div) < 0) {
|
||||
-- unusedRem;
|
||||
#if MP_ARGCHK == 2
|
||||
@ -4220,26 +4226,34 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
||||
-- MP_DIGITS(&part);
|
||||
++ MP_USED(&part);
|
||||
++ MP_ALLOC(&part);
|
||||
partExtended = 1;
|
||||
}
|
||||
|
||||
/* Compute a guess for the next quotient digit */
|
||||
q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
|
||||
div_msd = MP_DIGIT(div, MP_USED(div) - 1);
|
||||
if (q_msd >= div_msd) {
|
||||
if (!partExtended) {
|
||||
/* In this case, q_msd /= div_msd is always 1. First, since div_msd is
|
||||
* normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since
|
||||
* we didn't extend part, q_msd >= div_msd. Therefore we know that
|
||||
* div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we
|
||||
* get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */
|
||||
q_msd = 1;
|
||||
} else if (MP_USED(&part) > 1) {
|
||||
} else {
|
||||
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
|
||||
q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
|
||||
q_msd /= div_msd;
|
||||
if (q_msd == RADIX)
|
||||
--q_msd;
|
||||
#else
|
||||
mp_digit r;
|
||||
MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
|
||||
div_msd, &q_msd, &r) );
|
||||
if (q_msd == div_msd) {
|
||||
q_msd = MP_DIGIT_MAX;
|
||||
} else {
|
||||
mp_digit r;
|
||||
MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
|
||||
div_msd, &q_msd, &r) );
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
q_msd = 0;
|
||||
}
|
||||
#if MP_ARGCHK == 2
|
||||
assert(q_msd > 0); /* This case should never occur any more. */
|
||||
@ -4777,38 +4791,61 @@ mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ mp_to_fixlen_octets(mp, str) */
|
||||
/* output a buffer of big endian octets exactly as long as requested. */
|
||||
/* output a buffer of big endian octets exactly as long as requested.
|
||||
constant time on the value of mp. */
|
||||
mp_err
|
||||
mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
|
||||
{
|
||||
int ix, pos = 0;
|
||||
unsigned int bytes;
|
||||
int ix, jx;
|
||||
unsigned int bytes;
|
||||
|
||||
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
|
||||
ARGCHK(mp != NULL, MP_BADARG);
|
||||
ARGCHK(str != NULL, MP_BADARG);
|
||||
ARGCHK(!SIGN(mp), MP_BADARG);
|
||||
ARGCHK(length > 0, MP_BADARG);
|
||||
|
||||
bytes = mp_unsigned_octet_size(mp);
|
||||
ARGCHK(bytes <= length, MP_BADARG);
|
||||
/* Constant time on the value of mp. Don't use mp_unsigned_octet_size. */
|
||||
bytes = USED(mp) * MP_DIGIT_SIZE;
|
||||
|
||||
/* place any needed leading zeros */
|
||||
for (;length > bytes; --length) {
|
||||
*str++ = 0;
|
||||
/* If the output is shorter than the native size of mp, then check that any
|
||||
* bytes not written have zero values. This check isn't constant time on
|
||||
* the assumption that timing-sensitive callers can guarantee that mp fits
|
||||
* in the allocated space. */
|
||||
ix = USED(mp) - 1;
|
||||
if (bytes > length) {
|
||||
unsigned int zeros = bytes - length;
|
||||
|
||||
while (zeros >= MP_DIGIT_SIZE) {
|
||||
ARGCHK(DIGIT(mp, ix) == 0, MP_BADARG);
|
||||
zeros -= MP_DIGIT_SIZE;
|
||||
ix--;
|
||||
}
|
||||
|
||||
if (zeros > 0) {
|
||||
mp_digit d = DIGIT(mp, ix);
|
||||
mp_digit m = (mp_digit)~0 << ((MP_DIGIT_SIZE - zeros) * CHAR_BIT);
|
||||
ARGCHK((d & m) == 0, MP_BADARG);
|
||||
for (jx = MP_DIGIT_SIZE - zeros - 1; jx >= 0; jx--) {
|
||||
*str++ = d >> (jx * CHAR_BIT);
|
||||
}
|
||||
ix--;
|
||||
}
|
||||
} else if (bytes < length) {
|
||||
/* Place any needed leading zeros. */
|
||||
unsigned int zeros = length - bytes;
|
||||
memset(str, 0, zeros);
|
||||
str += zeros;
|
||||
}
|
||||
|
||||
/* Iterate over each digit... */
|
||||
for(ix = USED(mp) - 1; ix >= 0; ix--) {
|
||||
mp_digit d = DIGIT(mp, ix);
|
||||
int jx;
|
||||
/* Iterate over each whole digit... */
|
||||
for (; ix >= 0; ix--) {
|
||||
mp_digit d = DIGIT(mp, ix);
|
||||
|
||||
/* Unpack digit bytes, high order first */
|
||||
for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
|
||||
unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
|
||||
if (!pos && !x) /* suppress leading zeros */
|
||||
continue;
|
||||
str[pos++] = x;
|
||||
for (jx = MP_DIGIT_SIZE - 1; jx >= 0; jx--) {
|
||||
*str++ = d >> (jx * CHAR_BIT);
|
||||
}
|
||||
}
|
||||
if (!pos)
|
||||
str[pos++] = 0;
|
||||
return MP_OKAY;
|
||||
} /* end mp_to_fixlen_octets() */
|
||||
/* }}} */
|
||||
|
@ -125,7 +125,8 @@ typedef int mp_sword;
|
||||
#define MP_WORD_MAX UINT_MAX
|
||||
#endif
|
||||
|
||||
#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit))
|
||||
#define MP_DIGIT_SIZE sizeof(mp_digit)
|
||||
#define MP_DIGIT_BIT (CHAR_BIT * MP_DIGIT_SIZE)
|
||||
#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word))
|
||||
#define MP_RADIX (1+(mp_word)MP_DIGIT_MAX)
|
||||
|
||||
|
@ -8,6 +8,9 @@
|
||||
* Also NOTE: this only works with Hashing. Only the FIPS interface is enabled.
|
||||
*/
|
||||
|
||||
#ifndef _NSSLOWHASH_H_
|
||||
#define _NSSLOWHASH_H_
|
||||
|
||||
typedef struct NSSLOWInitContextStr NSSLOWInitContext;
|
||||
typedef struct NSSLOWHASHContextStr NSSLOWHASHContext;
|
||||
|
||||
@ -26,3 +29,5 @@ void NSSLOWHASH_End(NSSLOWHASHContext *context,
|
||||
unsigned int *ret, unsigned int len);
|
||||
void NSSLOWHASH_Destroy(NSSLOWHASHContext *context);
|
||||
unsigned int NSSLOWHASH_Length(NSSLOWHASHContext *context);
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,623 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* This implementation of poly1305 is by Andrew Moon
|
||||
* (https://github.com/floodyberry/poly1305-donna) and released as public
|
||||
* domain. It implements SIMD vectorization based on the algorithm described in
|
||||
* http://cr.yp.to/papers.html#neoncrypto. Unrolled to 2 powers, i.e. 64 byte
|
||||
* block size. */
|
||||
|
||||
#include <emmintrin.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "poly1305.h"
|
||||
|
||||
#define ALIGN(x) __attribute__((aligned(x)))
|
||||
#define INLINE inline
|
||||
#define U8TO64_LE(m) (*(uint64_t*)(m))
|
||||
#define U8TO32_LE(m) (*(uint32_t*)(m))
|
||||
#define U64TO8_LE(m,v) (*(uint64_t*)(m)) = v
|
||||
|
||||
typedef __m128i xmmi;
|
||||
typedef unsigned __int128 uint128_t;
|
||||
|
||||
static const uint32_t ALIGN(16) poly1305_x64_sse2_message_mask[4] = {(1 << 26) - 1, 0, (1 << 26) - 1, 0};
|
||||
static const uint32_t ALIGN(16) poly1305_x64_sse2_5[4] = {5, 0, 5, 0};
|
||||
static const uint32_t ALIGN(16) poly1305_x64_sse2_1shl128[4] = {(1 << 24), 0, (1 << 24), 0};
|
||||
|
||||
static uint128_t INLINE
|
||||
add128(uint128_t a, uint128_t b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
static uint128_t INLINE
|
||||
add128_64(uint128_t a, uint64_t b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
static uint128_t INLINE
|
||||
mul64x64_128(uint64_t a, uint64_t b) {
|
||||
return (uint128_t)a * b;
|
||||
}
|
||||
|
||||
static uint64_t INLINE
|
||||
lo128(uint128_t a) {
|
||||
return (uint64_t)a;
|
||||
}
|
||||
|
||||
static uint64_t INLINE
|
||||
shr128(uint128_t v, const int shift) {
|
||||
return (uint64_t)(v >> shift);
|
||||
}
|
||||
|
||||
static uint64_t INLINE
|
||||
shr128_pair(uint64_t hi, uint64_t lo, const int shift) {
|
||||
return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift);
|
||||
}
|
||||
|
||||
typedef struct poly1305_power_t {
|
||||
union {
|
||||
xmmi v;
|
||||
uint64_t u[2];
|
||||
uint32_t d[4];
|
||||
} R20,R21,R22,R23,R24,S21,S22,S23,S24;
|
||||
} poly1305_power;
|
||||
|
||||
typedef struct poly1305_state_internal_t {
|
||||
poly1305_power P[2]; /* 288 bytes, top 32 bit halves unused = 144 bytes of free storage */
|
||||
union {
|
||||
xmmi H[5]; /* 80 bytes */
|
||||
uint64_t HH[10];
|
||||
};
|
||||
/* uint64_t r0,r1,r2; [24 bytes] */
|
||||
/* uint64_t pad0,pad1; [16 bytes] */
|
||||
uint64_t started; /* 8 bytes */
|
||||
uint64_t leftover; /* 8 bytes */
|
||||
uint8_t buffer[64]; /* 64 bytes */
|
||||
} poly1305_state_internal; /* 448 bytes total + 63 bytes for alignment = 511 bytes raw */
|
||||
|
||||
static poly1305_state_internal INLINE
|
||||
*poly1305_aligned_state(poly1305_state *state) {
|
||||
return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63);
|
||||
}
|
||||
|
||||
/* copy 0-63 bytes */
|
||||
static void INLINE
|
||||
poly1305_block_copy(uint8_t *dst, const uint8_t *src, size_t bytes) {
|
||||
size_t offset = src - dst;
|
||||
if (bytes & 32) {
|
||||
_mm_storeu_si128((xmmi *)(dst + 0), _mm_loadu_si128((xmmi *)(dst + offset + 0)));
|
||||
_mm_storeu_si128((xmmi *)(dst + 16), _mm_loadu_si128((xmmi *)(dst + offset + 16)));
|
||||
dst += 32;
|
||||
}
|
||||
if (bytes & 16) { _mm_storeu_si128((xmmi *)dst, _mm_loadu_si128((xmmi *)(dst + offset))); dst += 16; }
|
||||
if (bytes & 8) { *(uint64_t *)dst = *(uint64_t *)(dst + offset); dst += 8; }
|
||||
if (bytes & 4) { *(uint32_t *)dst = *(uint32_t *)(dst + offset); dst += 4; }
|
||||
if (bytes & 2) { *(uint16_t *)dst = *(uint16_t *)(dst + offset); dst += 2; }
|
||||
if (bytes & 1) { *( uint8_t *)dst = *( uint8_t *)(dst + offset); }
|
||||
}
|
||||
|
||||
/* zero 0-15 bytes */
|
||||
static void INLINE
|
||||
poly1305_block_zero(uint8_t *dst, size_t bytes) {
|
||||
if (bytes & 8) { *(uint64_t *)dst = 0; dst += 8; }
|
||||
if (bytes & 4) { *(uint32_t *)dst = 0; dst += 4; }
|
||||
if (bytes & 2) { *(uint16_t *)dst = 0; dst += 2; }
|
||||
if (bytes & 1) { *( uint8_t *)dst = 0; }
|
||||
}
|
||||
|
||||
static size_t INLINE
|
||||
poly1305_min(size_t a, size_t b) {
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
void
|
||||
Poly1305Init(poly1305_state *state, const unsigned char key[32]) {
|
||||
poly1305_state_internal *st = poly1305_aligned_state(state);
|
||||
poly1305_power *p;
|
||||
uint64_t r0,r1,r2;
|
||||
uint64_t t0,t1;
|
||||
|
||||
/* clamp key */
|
||||
t0 = U8TO64_LE(key + 0);
|
||||
t1 = U8TO64_LE(key + 8);
|
||||
r0 = t0 & 0xffc0fffffff; t0 >>= 44; t0 |= t1 << 20;
|
||||
r1 = t0 & 0xfffffc0ffff; t1 >>= 24;
|
||||
r2 = t1 & 0x00ffffffc0f;
|
||||
|
||||
/* store r in un-used space of st->P[1] */
|
||||
p = &st->P[1];
|
||||
p->R20.d[1] = (uint32_t)(r0 );
|
||||
p->R20.d[3] = (uint32_t)(r0 >> 32);
|
||||
p->R21.d[1] = (uint32_t)(r1 );
|
||||
p->R21.d[3] = (uint32_t)(r1 >> 32);
|
||||
p->R22.d[1] = (uint32_t)(r2 );
|
||||
p->R22.d[3] = (uint32_t)(r2 >> 32);
|
||||
|
||||
/* store pad */
|
||||
p->R23.d[1] = U8TO32_LE(key + 16);
|
||||
p->R23.d[3] = U8TO32_LE(key + 20);
|
||||
p->R24.d[1] = U8TO32_LE(key + 24);
|
||||
p->R24.d[3] = U8TO32_LE(key + 28);
|
||||
|
||||
/* H = 0 */
|
||||
st->H[0] = _mm_setzero_si128();
|
||||
st->H[1] = _mm_setzero_si128();
|
||||
st->H[2] = _mm_setzero_si128();
|
||||
st->H[3] = _mm_setzero_si128();
|
||||
st->H[4] = _mm_setzero_si128();
|
||||
|
||||
st->started = 0;
|
||||
st->leftover = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
poly1305_first_block(poly1305_state_internal *st, const uint8_t *m) {
|
||||
const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
|
||||
const xmmi FIVE = _mm_load_si128((xmmi*)poly1305_x64_sse2_5);
|
||||
const xmmi HIBIT = _mm_load_si128((xmmi*)poly1305_x64_sse2_1shl128);
|
||||
xmmi T5,T6;
|
||||
poly1305_power *p;
|
||||
uint128_t d[3];
|
||||
uint64_t r0,r1,r2;
|
||||
uint64_t r20,r21,r22,s22;
|
||||
uint64_t pad0,pad1;
|
||||
uint64_t c;
|
||||
uint64_t i;
|
||||
|
||||
/* pull out stored info */
|
||||
p = &st->P[1];
|
||||
|
||||
r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
|
||||
r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
|
||||
r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
|
||||
pad0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1];
|
||||
pad1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1];
|
||||
|
||||
/* compute powers r^2,r^4 */
|
||||
r20 = r0;
|
||||
r21 = r1;
|
||||
r22 = r2;
|
||||
for (i = 0; i < 2; i++) {
|
||||
s22 = r22 * (5 << 2);
|
||||
|
||||
d[0] = add128(mul64x64_128(r20, r20), mul64x64_128(r21 * 2, s22));
|
||||
d[1] = add128(mul64x64_128(r22, s22), mul64x64_128(r20 * 2, r21));
|
||||
d[2] = add128(mul64x64_128(r21, r21), mul64x64_128(r22 * 2, r20));
|
||||
|
||||
r20 = lo128(d[0]) & 0xfffffffffff; c = shr128(d[0], 44);
|
||||
d[1] = add128_64(d[1], c); r21 = lo128(d[1]) & 0xfffffffffff; c = shr128(d[1], 44);
|
||||
d[2] = add128_64(d[2], c); r22 = lo128(d[2]) & 0x3ffffffffff; c = shr128(d[2], 42);
|
||||
r20 += c * 5; c = (r20 >> 44); r20 = r20 & 0xfffffffffff;
|
||||
r21 += c;
|
||||
|
||||
p->R20.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)( r20 ) & 0x3ffffff), _MM_SHUFFLE(1,0,1,0));
|
||||
p->R21.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r20 >> 26) | (r21 << 18)) & 0x3ffffff), _MM_SHUFFLE(1,0,1,0));
|
||||
p->R22.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 8) ) & 0x3ffffff), _MM_SHUFFLE(1,0,1,0));
|
||||
p->R23.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 34) | (r22 << 10)) & 0x3ffffff), _MM_SHUFFLE(1,0,1,0));
|
||||
p->R24.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r22 >> 16) ) ), _MM_SHUFFLE(1,0,1,0));
|
||||
p->S21.v = _mm_mul_epu32(p->R21.v, FIVE);
|
||||
p->S22.v = _mm_mul_epu32(p->R22.v, FIVE);
|
||||
p->S23.v = _mm_mul_epu32(p->R23.v, FIVE);
|
||||
p->S24.v = _mm_mul_epu32(p->R24.v, FIVE);
|
||||
p--;
|
||||
}
|
||||
|
||||
/* put saved info back */
|
||||
p = &st->P[1];
|
||||
p->R20.d[1] = (uint32_t)(r0 );
|
||||
p->R20.d[3] = (uint32_t)(r0 >> 32);
|
||||
p->R21.d[1] = (uint32_t)(r1 );
|
||||
p->R21.d[3] = (uint32_t)(r1 >> 32);
|
||||
p->R22.d[1] = (uint32_t)(r2 );
|
||||
p->R22.d[3] = (uint32_t)(r2 >> 32);
|
||||
p->R23.d[1] = (uint32_t)(pad0 );
|
||||
p->R23.d[3] = (uint32_t)(pad0 >> 32);
|
||||
p->R24.d[1] = (uint32_t)(pad1 );
|
||||
p->R24.d[3] = (uint32_t)(pad1 >> 32);
|
||||
|
||||
/* H = [Mx,My] */
|
||||
T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
|
||||
T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
|
||||
st->H[0] = _mm_and_si128(MMASK, T5);
|
||||
st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
|
||||
st->H[2] = _mm_and_si128(MMASK, T5);
|
||||
st->H[3] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
st->H[4] = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
|
||||
}
|
||||
|
||||
static void
|
||||
poly1305_blocks(poly1305_state_internal *st, const uint8_t *m, size_t bytes) {
|
||||
const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
|
||||
const xmmi FIVE = _mm_load_si128((xmmi*)poly1305_x64_sse2_5);
|
||||
const xmmi HIBIT = _mm_load_si128((xmmi*)poly1305_x64_sse2_1shl128);
|
||||
|
||||
poly1305_power *p;
|
||||
xmmi H0,H1,H2,H3,H4;
|
||||
xmmi T0,T1,T2,T3,T4,T5,T6;
|
||||
xmmi M0,M1,M2,M3,M4;
|
||||
xmmi C1,C2;
|
||||
|
||||
H0 = st->H[0];
|
||||
H1 = st->H[1];
|
||||
H2 = st->H[2];
|
||||
H3 = st->H[3];
|
||||
H4 = st->H[4];
|
||||
|
||||
while (bytes >= 64) {
|
||||
/* H *= [r^4,r^4] */
|
||||
p = &st->P[0];
|
||||
T0 = _mm_mul_epu32(H0, p->R20.v);
|
||||
T1 = _mm_mul_epu32(H0, p->R21.v);
|
||||
T2 = _mm_mul_epu32(H0, p->R22.v);
|
||||
T3 = _mm_mul_epu32(H0, p->R23.v);
|
||||
T4 = _mm_mul_epu32(H0, p->R24.v);
|
||||
T5 = _mm_mul_epu32(H1, p->S24.v); T6 = _mm_mul_epu32(H1, p->R20.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->S23.v); T6 = _mm_mul_epu32(H2, p->S24.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S22.v); T6 = _mm_mul_epu32(H3, p->S23.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S21.v); T6 = _mm_mul_epu32(H4, p->S22.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R21.v); T6 = _mm_mul_epu32(H1, p->R22.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->R20.v); T6 = _mm_mul_epu32(H2, p->R21.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S24.v); T6 = _mm_mul_epu32(H3, p->R20.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S23.v); T6 = _mm_mul_epu32(H4, p->S24.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R23.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H2, p->R22.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H3, p->R21.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H4, p->R20.v); T4 = _mm_add_epi64(T4, T5);
|
||||
|
||||
/* H += [Mx,My]*[r^2,r^2] */
|
||||
T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
|
||||
T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
|
||||
M0 = _mm_and_si128(MMASK, T5);
|
||||
M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
|
||||
M2 = _mm_and_si128(MMASK, T5);
|
||||
M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
|
||||
|
||||
p = &st->P[1];
|
||||
T5 = _mm_mul_epu32(M0, p->R20.v); T6 = _mm_mul_epu32(M0, p->R21.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M1, p->S24.v); T6 = _mm_mul_epu32(M1, p->R20.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M2, p->S23.v); T6 = _mm_mul_epu32(M2, p->S24.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M3, p->S22.v); T6 = _mm_mul_epu32(M3, p->S23.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M4, p->S21.v); T6 = _mm_mul_epu32(M4, p->S22.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M0, p->R22.v); T6 = _mm_mul_epu32(M0, p->R23.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M1, p->R21.v); T6 = _mm_mul_epu32(M1, p->R22.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M2, p->R20.v); T6 = _mm_mul_epu32(M2, p->R21.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M3, p->S24.v); T6 = _mm_mul_epu32(M3, p->R20.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M4, p->S23.v); T6 = _mm_mul_epu32(M4, p->S24.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M0, p->R24.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(M1, p->R23.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(M2, p->R22.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(M3, p->R21.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(M4, p->R20.v); T4 = _mm_add_epi64(T4, T5);
|
||||
|
||||
/* H += [Mx,My] */
|
||||
T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 32)), _mm_loadl_epi64((xmmi *)(m + 48)));
|
||||
T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 40)), _mm_loadl_epi64((xmmi *)(m + 56)));
|
||||
M0 = _mm_and_si128(MMASK, T5);
|
||||
M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
|
||||
M2 = _mm_and_si128(MMASK, T5);
|
||||
M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
|
||||
|
||||
T0 = _mm_add_epi64(T0, M0);
|
||||
T1 = _mm_add_epi64(T1, M1);
|
||||
T2 = _mm_add_epi64(T2, M2);
|
||||
T3 = _mm_add_epi64(T3, M3);
|
||||
T4 = _mm_add_epi64(T4, M4);
|
||||
|
||||
/* reduce */
|
||||
C1 = _mm_srli_epi64(T0, 26); C2 = _mm_srli_epi64(T3, 26); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_and_si128(T3, MMASK); T1 = _mm_add_epi64(T1, C1); T4 = _mm_add_epi64(T4, C2);
|
||||
C1 = _mm_srli_epi64(T1, 26); C2 = _mm_srli_epi64(T4, 26); T1 = _mm_and_si128(T1, MMASK); T4 = _mm_and_si128(T4, MMASK); T2 = _mm_add_epi64(T2, C1); T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
|
||||
C1 = _mm_srli_epi64(T2, 26); C2 = _mm_srli_epi64(T0, 26); T2 = _mm_and_si128(T2, MMASK); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_add_epi64(T3, C1); T1 = _mm_add_epi64(T1, C2);
|
||||
C1 = _mm_srli_epi64(T3, 26); T3 = _mm_and_si128(T3, MMASK); T4 = _mm_add_epi64(T4, C1);
|
||||
|
||||
/* H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx,My]) */
|
||||
H0 = T0;
|
||||
H1 = T1;
|
||||
H2 = T2;
|
||||
H3 = T3;
|
||||
H4 = T4;
|
||||
|
||||
m += 64;
|
||||
bytes -= 64;
|
||||
}
|
||||
|
||||
st->H[0] = H0;
|
||||
st->H[1] = H1;
|
||||
st->H[2] = H2;
|
||||
st->H[3] = H3;
|
||||
st->H[4] = H4;
|
||||
}
|
||||
|
||||
static size_t
|
||||
poly1305_combine(poly1305_state_internal *st, const uint8_t *m, size_t bytes) {
|
||||
const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
|
||||
const xmmi HIBIT = _mm_load_si128((xmmi*)poly1305_x64_sse2_1shl128);
|
||||
const xmmi FIVE = _mm_load_si128((xmmi*)poly1305_x64_sse2_5);
|
||||
|
||||
poly1305_power *p;
|
||||
xmmi H0,H1,H2,H3,H4;
|
||||
xmmi M0,M1,M2,M3,M4;
|
||||
xmmi T0,T1,T2,T3,T4,T5,T6;
|
||||
xmmi C1,C2;
|
||||
|
||||
uint64_t r0,r1,r2;
|
||||
uint64_t t0,t1,t2,t3,t4;
|
||||
uint64_t c;
|
||||
size_t consumed = 0;
|
||||
|
||||
H0 = st->H[0];
|
||||
H1 = st->H[1];
|
||||
H2 = st->H[2];
|
||||
H3 = st->H[3];
|
||||
H4 = st->H[4];
|
||||
|
||||
/* p = [r^2,r^2] */
|
||||
p = &st->P[1];
|
||||
|
||||
if (bytes >= 32) {
|
||||
/* H *= [r^2,r^2] */
|
||||
T0 = _mm_mul_epu32(H0, p->R20.v);
|
||||
T1 = _mm_mul_epu32(H0, p->R21.v);
|
||||
T2 = _mm_mul_epu32(H0, p->R22.v);
|
||||
T3 = _mm_mul_epu32(H0, p->R23.v);
|
||||
T4 = _mm_mul_epu32(H0, p->R24.v);
|
||||
T5 = _mm_mul_epu32(H1, p->S24.v); T6 = _mm_mul_epu32(H1, p->R20.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->S23.v); T6 = _mm_mul_epu32(H2, p->S24.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S22.v); T6 = _mm_mul_epu32(H3, p->S23.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S21.v); T6 = _mm_mul_epu32(H4, p->S22.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R21.v); T6 = _mm_mul_epu32(H1, p->R22.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->R20.v); T6 = _mm_mul_epu32(H2, p->R21.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S24.v); T6 = _mm_mul_epu32(H3, p->R20.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S23.v); T6 = _mm_mul_epu32(H4, p->S24.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R23.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H2, p->R22.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H3, p->R21.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H4, p->R20.v); T4 = _mm_add_epi64(T4, T5);
|
||||
|
||||
/* H += [Mx,My] */
|
||||
T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
|
||||
T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
|
||||
M0 = _mm_and_si128(MMASK, T5);
|
||||
M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
|
||||
M2 = _mm_and_si128(MMASK, T5);
|
||||
M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
|
||||
|
||||
T0 = _mm_add_epi64(T0, M0);
|
||||
T1 = _mm_add_epi64(T1, M1);
|
||||
T2 = _mm_add_epi64(T2, M2);
|
||||
T3 = _mm_add_epi64(T3, M3);
|
||||
T4 = _mm_add_epi64(T4, M4);
|
||||
|
||||
/* reduce */
|
||||
C1 = _mm_srli_epi64(T0, 26); C2 = _mm_srli_epi64(T3, 26); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_and_si128(T3, MMASK); T1 = _mm_add_epi64(T1, C1); T4 = _mm_add_epi64(T4, C2);
|
||||
C1 = _mm_srli_epi64(T1, 26); C2 = _mm_srli_epi64(T4, 26); T1 = _mm_and_si128(T1, MMASK); T4 = _mm_and_si128(T4, MMASK); T2 = _mm_add_epi64(T2, C1); T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
|
||||
C1 = _mm_srli_epi64(T2, 26); C2 = _mm_srli_epi64(T0, 26); T2 = _mm_and_si128(T2, MMASK); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_add_epi64(T3, C1); T1 = _mm_add_epi64(T1, C2);
|
||||
C1 = _mm_srli_epi64(T3, 26); T3 = _mm_and_si128(T3, MMASK); T4 = _mm_add_epi64(T4, C1);
|
||||
|
||||
/* H = (H*[r^2,r^2] + [Mx,My]) */
|
||||
H0 = T0;
|
||||
H1 = T1;
|
||||
H2 = T2;
|
||||
H3 = T3;
|
||||
H4 = T4;
|
||||
|
||||
consumed = 32;
|
||||
}
|
||||
|
||||
/* finalize, H *= [r^2,r] */
|
||||
r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
|
||||
r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
|
||||
r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
|
||||
|
||||
p->R20.d[2] = (uint32_t)( r0 ) & 0x3ffffff;
|
||||
p->R21.d[2] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff;
|
||||
p->R22.d[2] = (uint32_t)((r1 >> 8) ) & 0x3ffffff;
|
||||
p->R23.d[2] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff;
|
||||
p->R24.d[2] = (uint32_t)((r2 >> 16) ) ;
|
||||
p->S21.d[2] = p->R21.d[2] * 5;
|
||||
p->S22.d[2] = p->R22.d[2] * 5;
|
||||
p->S23.d[2] = p->R23.d[2] * 5;
|
||||
p->S24.d[2] = p->R24.d[2] * 5;
|
||||
|
||||
/* H *= [r^2,r] */
|
||||
T0 = _mm_mul_epu32(H0, p->R20.v);
|
||||
T1 = _mm_mul_epu32(H0, p->R21.v);
|
||||
T2 = _mm_mul_epu32(H0, p->R22.v);
|
||||
T3 = _mm_mul_epu32(H0, p->R23.v);
|
||||
T4 = _mm_mul_epu32(H0, p->R24.v);
|
||||
T5 = _mm_mul_epu32(H1, p->S24.v); T6 = _mm_mul_epu32(H1, p->R20.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->S23.v); T6 = _mm_mul_epu32(H2, p->S24.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S22.v); T6 = _mm_mul_epu32(H3, p->S23.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S21.v); T6 = _mm_mul_epu32(H4, p->S22.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R21.v); T6 = _mm_mul_epu32(H1, p->R22.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->R20.v); T6 = _mm_mul_epu32(H2, p->R21.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S24.v); T6 = _mm_mul_epu32(H3, p->R20.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S23.v); T6 = _mm_mul_epu32(H4, p->S24.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R23.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H2, p->R22.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H3, p->R21.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H4, p->R20.v); T4 = _mm_add_epi64(T4, T5);
|
||||
|
||||
C1 = _mm_srli_epi64(T0, 26); C2 = _mm_srli_epi64(T3, 26); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_and_si128(T3, MMASK); T1 = _mm_add_epi64(T1, C1); T4 = _mm_add_epi64(T4, C2);
|
||||
C1 = _mm_srli_epi64(T1, 26); C2 = _mm_srli_epi64(T4, 26); T1 = _mm_and_si128(T1, MMASK); T4 = _mm_and_si128(T4, MMASK); T2 = _mm_add_epi64(T2, C1); T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
|
||||
C1 = _mm_srli_epi64(T2, 26); C2 = _mm_srli_epi64(T0, 26); T2 = _mm_and_si128(T2, MMASK); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_add_epi64(T3, C1); T1 = _mm_add_epi64(T1, C2);
|
||||
C1 = _mm_srli_epi64(T3, 26); T3 = _mm_and_si128(T3, MMASK); T4 = _mm_add_epi64(T4, C1);
|
||||
|
||||
/* H = H[0]+H[1] */
|
||||
H0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8));
|
||||
H1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8));
|
||||
H2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8));
|
||||
H3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8));
|
||||
H4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8));
|
||||
|
||||
t0 = _mm_cvtsi128_si32(H0) ; c = (t0 >> 26); t0 &= 0x3ffffff;
|
||||
t1 = _mm_cvtsi128_si32(H1) + c; c = (t1 >> 26); t1 &= 0x3ffffff;
|
||||
t2 = _mm_cvtsi128_si32(H2) + c; c = (t2 >> 26); t2 &= 0x3ffffff;
|
||||
t3 = _mm_cvtsi128_si32(H3) + c; c = (t3 >> 26); t3 &= 0x3ffffff;
|
||||
t4 = _mm_cvtsi128_si32(H4) + c; c = (t4 >> 26); t4 &= 0x3ffffff;
|
||||
t0 = t0 + (c * 5); c = (t0 >> 26); t0 &= 0x3ffffff;
|
||||
t1 = t1 + c;
|
||||
|
||||
st->HH[0] = ((t0 ) | (t1 << 26) ) & 0xfffffffffffull;
|
||||
st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & 0xfffffffffffull;
|
||||
st->HH[2] = ((t3 >> 10) | (t4 << 16) ) & 0x3ffffffffffull;
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void
|
||||
Poly1305Update(poly1305_state *state, const unsigned char *m, size_t bytes) {
|
||||
poly1305_state_internal *st = poly1305_aligned_state(state);
|
||||
size_t want;
|
||||
|
||||
/* need at least 32 initial bytes to start the accelerated branch */
|
||||
if (!st->started) {
|
||||
if ((st->leftover == 0) && (bytes > 32)) {
|
||||
poly1305_first_block(st, m);
|
||||
m += 32;
|
||||
bytes -= 32;
|
||||
} else {
|
||||
want = poly1305_min(32 - st->leftover, bytes);
|
||||
poly1305_block_copy(st->buffer + st->leftover, m, want);
|
||||
bytes -= want;
|
||||
m += want;
|
||||
st->leftover += want;
|
||||
if ((st->leftover < 32) || (bytes == 0))
|
||||
return;
|
||||
poly1305_first_block(st, st->buffer);
|
||||
st->leftover = 0;
|
||||
}
|
||||
st->started = 1;
|
||||
}
|
||||
|
||||
/* handle leftover */
|
||||
if (st->leftover) {
|
||||
want = poly1305_min(64 - st->leftover, bytes);
|
||||
poly1305_block_copy(st->buffer + st->leftover, m, want);
|
||||
bytes -= want;
|
||||
m += want;
|
||||
st->leftover += want;
|
||||
if (st->leftover < 64)
|
||||
return;
|
||||
poly1305_blocks(st, st->buffer, 64);
|
||||
st->leftover = 0;
|
||||
}
|
||||
|
||||
/* process 64 byte blocks */
|
||||
if (bytes >= 64) {
|
||||
want = (bytes & ~63);
|
||||
poly1305_blocks(st, m, want);
|
||||
m += want;
|
||||
bytes -= want;
|
||||
}
|
||||
|
||||
if (bytes) {
|
||||
poly1305_block_copy(st->buffer + st->leftover, m, bytes);
|
||||
st->leftover += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Poly1305Finish(poly1305_state *state, unsigned char mac[16]) {
|
||||
poly1305_state_internal *st = poly1305_aligned_state(state);
|
||||
size_t leftover = st->leftover;
|
||||
uint8_t *m = st->buffer;
|
||||
uint128_t d[3];
|
||||
uint64_t h0,h1,h2;
|
||||
uint64_t t0,t1;
|
||||
uint64_t g0,g1,g2,c,nc;
|
||||
uint64_t r0,r1,r2,s1,s2;
|
||||
poly1305_power *p;
|
||||
|
||||
if (st->started) {
|
||||
size_t consumed = poly1305_combine(st, m, leftover);
|
||||
leftover -= consumed;
|
||||
m += consumed;
|
||||
}
|
||||
|
||||
/* st->HH will either be 0 or have the combined result */
|
||||
h0 = st->HH[0];
|
||||
h1 = st->HH[1];
|
||||
h2 = st->HH[2];
|
||||
|
||||
p = &st->P[1];
|
||||
r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
|
||||
r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
|
||||
r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
|
||||
s1 = r1 * (5 << 2);
|
||||
s2 = r2 * (5 << 2);
|
||||
|
||||
if (leftover < 16)
|
||||
goto poly1305_donna_atmost15bytes;
|
||||
|
||||
poly1305_donna_atleast16bytes:
|
||||
t0 = U8TO64_LE(m + 0);
|
||||
t1 = U8TO64_LE(m + 8);
|
||||
h0 += t0 & 0xfffffffffff;
|
||||
t0 = shr128_pair(t1, t0, 44);
|
||||
h1 += t0 & 0xfffffffffff;
|
||||
h2 += (t1 >> 24) | ((uint64_t)1 << 40);
|
||||
|
||||
poly1305_donna_mul:
|
||||
d[0] = add128(add128(mul64x64_128(h0, r0), mul64x64_128(h1, s2)), mul64x64_128(h2, s1));
|
||||
d[1] = add128(add128(mul64x64_128(h0, r1), mul64x64_128(h1, r0)), mul64x64_128(h2, s2));
|
||||
d[2] = add128(add128(mul64x64_128(h0, r2), mul64x64_128(h1, r1)), mul64x64_128(h2, r0));
|
||||
h0 = lo128(d[0]) & 0xfffffffffff; c = shr128(d[0], 44);
|
||||
d[1] = add128_64(d[1], c); h1 = lo128(d[1]) & 0xfffffffffff; c = shr128(d[1], 44);
|
||||
d[2] = add128_64(d[2], c); h2 = lo128(d[2]) & 0x3ffffffffff; c = shr128(d[2], 42);
|
||||
h0 += c * 5;
|
||||
|
||||
m += 16;
|
||||
leftover -= 16;
|
||||
if (leftover >= 16) goto poly1305_donna_atleast16bytes;
|
||||
|
||||
/* final bytes */
|
||||
poly1305_donna_atmost15bytes:
|
||||
if (!leftover) goto poly1305_donna_finish;
|
||||
|
||||
m[leftover++] = 1;
|
||||
poly1305_block_zero(m + leftover, 16 - leftover);
|
||||
leftover = 16;
|
||||
|
||||
t0 = U8TO64_LE(m+0);
|
||||
t1 = U8TO64_LE(m+8);
|
||||
h0 += t0 & 0xfffffffffff; t0 = shr128_pair(t1, t0, 44);
|
||||
h1 += t0 & 0xfffffffffff;
|
||||
h2 += (t1 >> 24);
|
||||
|
||||
goto poly1305_donna_mul;
|
||||
|
||||
poly1305_donna_finish:
|
||||
c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5;
|
||||
|
||||
g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff;
|
||||
g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff;
|
||||
g2 = h2 + c - ((uint64_t)1 << 42);
|
||||
|
||||
c = (g2 >> 63) - 1;
|
||||
nc = ~c;
|
||||
h0 = (h0 & nc) | (g0 & c);
|
||||
h1 = (h1 & nc) | (g1 & c);
|
||||
h2 = (h2 & nc) | (g2 & c);
|
||||
|
||||
/* pad */
|
||||
t0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1];
|
||||
t1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1];
|
||||
h0 += (t0 & 0xfffffffffff) ; c = (h0 >> 44); h0 &= 0xfffffffffff; t0 = shr128_pair(t1, t0, 44);
|
||||
h1 += (t0 & 0xfffffffffff) + c; c = (h1 >> 44); h1 &= 0xfffffffffff; t1 = (t1 >> 24);
|
||||
h2 += (t1 ) + c;
|
||||
|
||||
U64TO8_LE(mac + 0, ((h0 ) | (h1 << 44)));
|
||||
U64TO8_LE(mac + 8, ((h1 >> 20) | (h2 << 24)));
|
||||
}
|
261
security/nss/lib/freebl/poly1305.c
Normal file
261
security/nss/lib/freebl/poly1305.c
Normal file
@ -0,0 +1,261 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* This implementation of poly1305 is by Andrew Moon
|
||||
* (https://github.com/floodyberry/poly1305-donna) and released as public
|
||||
* domain. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "poly1305.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
#include "prtypes.h"
|
||||
typedef PRUint32 uint32_t;
|
||||
typedef PRUint64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if defined(NSS_X86) || defined(NSS_X64)
|
||||
/* We can assume little-endian. */
|
||||
static uint32_t U8TO32_LE(const unsigned char *m) {
|
||||
uint32_t r;
|
||||
memcpy(&r, m, sizeof(r));
|
||||
return r;
|
||||
}
|
||||
|
||||
static void U32TO8_LE(unsigned char *m, uint32_t v) {
|
||||
memcpy(m, &v, sizeof(v));
|
||||
}
|
||||
#else
|
||||
static uint32_t U8TO32_LE(const unsigned char *m) {
|
||||
return (uint32_t)m[0] |
|
||||
(uint32_t)m[1] << 8 |
|
||||
(uint32_t)m[2] << 16 |
|
||||
(uint32_t)m[3] << 24;
|
||||
}
|
||||
|
||||
static void U32TO8_LE(unsigned char *m, uint32_t v) {
|
||||
m[0] = v;
|
||||
m[1] = v >> 8;
|
||||
m[2] = v >> 16;
|
||||
m[3] = v >> 24;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint64_t
|
||||
mul32x32_64(uint32_t a, uint32_t b) {
|
||||
return (uint64_t)a * b;
|
||||
}
|
||||
|
||||
struct poly1305_state_st {
|
||||
uint32_t r0,r1,r2,r3,r4;
|
||||
uint32_t s1,s2,s3,s4;
|
||||
uint32_t h0,h1,h2,h3,h4;
|
||||
unsigned char buf[16];
|
||||
unsigned int buf_used;
|
||||
unsigned char key[16];
|
||||
};
|
||||
|
||||
/* update updates |state| given some amount of input data. This function may
|
||||
* only be called with a |len| that is not a multiple of 16 at the end of the
|
||||
* data. Otherwise the input must be buffered into 16 byte blocks. */
|
||||
static void update(struct poly1305_state_st *state, const unsigned char *in,
|
||||
size_t len) {
|
||||
uint32_t t0,t1,t2,t3;
|
||||
uint64_t t[5];
|
||||
uint32_t b;
|
||||
uint64_t c;
|
||||
size_t j;
|
||||
unsigned char mp[16];
|
||||
|
||||
if (len < 16)
|
||||
goto poly1305_donna_atmost15bytes;
|
||||
|
||||
poly1305_donna_16bytes:
|
||||
t0 = U8TO32_LE(in);
|
||||
t1 = U8TO32_LE(in+4);
|
||||
t2 = U8TO32_LE(in+8);
|
||||
t3 = U8TO32_LE(in+12);
|
||||
|
||||
in += 16;
|
||||
len -= 16;
|
||||
|
||||
state->h0 += t0 & 0x3ffffff;
|
||||
state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
|
||||
state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
|
||||
state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
|
||||
state->h4 += (t3 >> 8) | (1 << 24);
|
||||
|
||||
poly1305_donna_mul:
|
||||
t[0] = mul32x32_64(state->h0,state->r0) +
|
||||
mul32x32_64(state->h1,state->s4) +
|
||||
mul32x32_64(state->h2,state->s3) +
|
||||
mul32x32_64(state->h3,state->s2) +
|
||||
mul32x32_64(state->h4,state->s1);
|
||||
t[1] = mul32x32_64(state->h0,state->r1) +
|
||||
mul32x32_64(state->h1,state->r0) +
|
||||
mul32x32_64(state->h2,state->s4) +
|
||||
mul32x32_64(state->h3,state->s3) +
|
||||
mul32x32_64(state->h4,state->s2);
|
||||
t[2] = mul32x32_64(state->h0,state->r2) +
|
||||
mul32x32_64(state->h1,state->r1) +
|
||||
mul32x32_64(state->h2,state->r0) +
|
||||
mul32x32_64(state->h3,state->s4) +
|
||||
mul32x32_64(state->h4,state->s3);
|
||||
t[3] = mul32x32_64(state->h0,state->r3) +
|
||||
mul32x32_64(state->h1,state->r2) +
|
||||
mul32x32_64(state->h2,state->r1) +
|
||||
mul32x32_64(state->h3,state->r0) +
|
||||
mul32x32_64(state->h4,state->s4);
|
||||
t[4] = mul32x32_64(state->h0,state->r4) +
|
||||
mul32x32_64(state->h1,state->r3) +
|
||||
mul32x32_64(state->h2,state->r2) +
|
||||
mul32x32_64(state->h3,state->r1) +
|
||||
mul32x32_64(state->h4,state->r0);
|
||||
|
||||
state->h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26);
|
||||
t[1] += c; state->h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26);
|
||||
t[2] += b; state->h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26);
|
||||
t[3] += b; state->h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26);
|
||||
t[4] += b; state->h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26);
|
||||
state->h0 += b * 5;
|
||||
|
||||
if (len >= 16)
|
||||
goto poly1305_donna_16bytes;
|
||||
|
||||
/* final bytes */
|
||||
poly1305_donna_atmost15bytes:
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
for (j = 0; j < len; j++)
|
||||
mp[j] = in[j];
|
||||
mp[j++] = 1;
|
||||
for (; j < 16; j++)
|
||||
mp[j] = 0;
|
||||
len = 0;
|
||||
|
||||
t0 = U8TO32_LE(mp+0);
|
||||
t1 = U8TO32_LE(mp+4);
|
||||
t2 = U8TO32_LE(mp+8);
|
||||
t3 = U8TO32_LE(mp+12);
|
||||
|
||||
state->h0 += t0 & 0x3ffffff;
|
||||
state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
|
||||
state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
|
||||
state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
|
||||
state->h4 += (t3 >> 8);
|
||||
|
||||
goto poly1305_donna_mul;
|
||||
}
|
||||
|
||||
void Poly1305Init(poly1305_state *statep, const unsigned char key[32]) {
|
||||
struct poly1305_state_st *state = (struct poly1305_state_st*) statep;
|
||||
uint32_t t0,t1,t2,t3;
|
||||
|
||||
t0 = U8TO32_LE(key+0);
|
||||
t1 = U8TO32_LE(key+4);
|
||||
t2 = U8TO32_LE(key+8);
|
||||
t3 = U8TO32_LE(key+12);
|
||||
|
||||
/* precompute multipliers */
|
||||
state->r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
|
||||
state->r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
|
||||
state->r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
|
||||
state->r3 = t2 & 0x3f03fff; t3 >>= 8;
|
||||
state->r4 = t3 & 0x00fffff;
|
||||
|
||||
state->s1 = state->r1 * 5;
|
||||
state->s2 = state->r2 * 5;
|
||||
state->s3 = state->r3 * 5;
|
||||
state->s4 = state->r4 * 5;
|
||||
|
||||
/* init state */
|
||||
state->h0 = 0;
|
||||
state->h1 = 0;
|
||||
state->h2 = 0;
|
||||
state->h3 = 0;
|
||||
state->h4 = 0;
|
||||
|
||||
state->buf_used = 0;
|
||||
memcpy(state->key, key + 16, sizeof(state->key));
|
||||
}
|
||||
|
||||
void Poly1305Update(poly1305_state *statep, const unsigned char *in,
|
||||
size_t in_len) {
|
||||
unsigned int i;
|
||||
struct poly1305_state_st *state = (struct poly1305_state_st*) statep;
|
||||
|
||||
if (state->buf_used) {
|
||||
unsigned int todo = 16 - state->buf_used;
|
||||
if (todo > in_len)
|
||||
todo = in_len;
|
||||
for (i = 0; i < todo; i++)
|
||||
state->buf[state->buf_used + i] = in[i];
|
||||
state->buf_used += todo;
|
||||
in_len -= todo;
|
||||
in += todo;
|
||||
|
||||
if (state->buf_used == 16) {
|
||||
update(state, state->buf, 16);
|
||||
state->buf_used = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_len >= 16) {
|
||||
size_t todo = in_len & ~0xf;
|
||||
update(state, in, todo);
|
||||
in += todo;
|
||||
in_len &= 0xf;
|
||||
}
|
||||
|
||||
if (in_len) {
|
||||
for (i = 0; i < in_len; i++)
|
||||
state->buf[i] = in[i];
|
||||
state->buf_used = in_len;
|
||||
}
|
||||
}
|
||||
|
||||
void Poly1305Finish(poly1305_state *statep, unsigned char mac[16]) {
|
||||
struct poly1305_state_st *state = (struct poly1305_state_st*) statep;
|
||||
uint64_t f0,f1,f2,f3;
|
||||
uint32_t g0,g1,g2,g3,g4;
|
||||
uint32_t b, nb;
|
||||
|
||||
if (state->buf_used)
|
||||
update(state, state->buf, state->buf_used);
|
||||
|
||||
b = state->h0 >> 26; state->h0 = state->h0 & 0x3ffffff;
|
||||
state->h1 += b; b = state->h1 >> 26; state->h1 = state->h1 & 0x3ffffff;
|
||||
state->h2 += b; b = state->h2 >> 26; state->h2 = state->h2 & 0x3ffffff;
|
||||
state->h3 += b; b = state->h3 >> 26; state->h3 = state->h3 & 0x3ffffff;
|
||||
state->h4 += b; b = state->h4 >> 26; state->h4 = state->h4 & 0x3ffffff;
|
||||
state->h0 += b * 5;
|
||||
|
||||
g0 = state->h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
|
||||
g1 = state->h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
|
||||
g2 = state->h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
|
||||
g3 = state->h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
|
||||
g4 = state->h4 + b - (1 << 26);
|
||||
|
||||
b = (g4 >> 31) - 1;
|
||||
nb = ~b;
|
||||
state->h0 = (state->h0 & nb) | (g0 & b);
|
||||
state->h1 = (state->h1 & nb) | (g1 & b);
|
||||
state->h2 = (state->h2 & nb) | (g2 & b);
|
||||
state->h3 = (state->h3 & nb) | (g3 & b);
|
||||
state->h4 = (state->h4 & nb) | (g4 & b);
|
||||
|
||||
f0 = ((state->h0 ) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]);
|
||||
f1 = ((state->h1 >> 6) | (state->h2 << 20)) + (uint64_t)U8TO32_LE(&state->key[4]);
|
||||
f2 = ((state->h2 >> 12) | (state->h3 << 14)) + (uint64_t)U8TO32_LE(&state->key[8]);
|
||||
f3 = ((state->h3 >> 18) | (state->h4 << 8)) + (uint64_t)U8TO32_LE(&state->key[12]);
|
||||
|
||||
U32TO8_LE(&mac[ 0], (uint32_t)f0); f1 += (f0 >> 32);
|
||||
U32TO8_LE(&mac[ 4], (uint32_t)f1); f2 += (f1 >> 32);
|
||||
U32TO8_LE(&mac[ 8], (uint32_t)f2); f3 += (f2 >> 32);
|
||||
U32TO8_LE(&mac[12], (uint32_t)f3);
|
||||
}
|
28
security/nss/lib/freebl/poly1305.h
Normal file
28
security/nss/lib/freebl/poly1305.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* poly1305.h - header file for Poly1305 implementation.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef FREEBL_POLY1305_H_
|
||||
#define FREEBL_POLY1305_H_
|
||||
|
||||
typedef unsigned char poly1305_state[512];
|
||||
|
||||
/* Poly1305Init sets up |state| so that it can be used to calculate an
|
||||
* authentication tag with the one-time key |key|. Note that |key| is a
|
||||
* one-time key and therefore there is no `reset' method because that would
|
||||
* enable several messages to be authenticated with the same key. */
|
||||
extern void Poly1305Init(poly1305_state* state, const unsigned char key[32]);
|
||||
|
||||
/* Poly1305Update processes |in_len| bytes from |in|. It can be called zero or
|
||||
* more times after poly1305_init. */
|
||||
extern void Poly1305Update(poly1305_state* state, const unsigned char* in,
|
||||
size_t inLen);
|
||||
|
||||
/* Poly1305Finish completes the poly1305 calculation and writes a 16 byte
|
||||
* authentication tag to |mac|. */
|
||||
extern void Poly1305Finish(poly1305_state* state, unsigned char mac[16]);
|
||||
|
||||
#endif /* FREEBL_POLY1305_H_ */
|
@ -1143,7 +1143,7 @@ makeGfromIndex(HASH_HashType hashtype,
|
||||
unsigned int len;
|
||||
mp_err err = MP_OKAY;
|
||||
SECStatus rv = SECSuccess;
|
||||
const SECHashObject *hashobj;
|
||||
const SECHashObject *hashobj = NULL;
|
||||
void *hashcx = NULL;
|
||||
|
||||
MP_DIGITS(&e) = 0;
|
||||
|
@ -907,48 +907,56 @@ RSA_DecryptBlock(RSAPrivateKey * key,
|
||||
const unsigned char * input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
SECStatus rv;
|
||||
PRInt8 rv;
|
||||
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
|
||||
unsigned int i;
|
||||
unsigned char * buffer;
|
||||
unsigned char *buffer = NULL;
|
||||
unsigned int outLen = 0;
|
||||
unsigned int copyOutLen = modulusLen - 11;
|
||||
|
||||
if (inputLen != modulusLen)
|
||||
goto failure;
|
||||
|
||||
buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
|
||||
if (!buffer)
|
||||
goto failure;
|
||||
|
||||
rv = RSA_PrivateKeyOp(key, buffer, input);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* XXX(rsleevi): Constant time */
|
||||
if (buffer[0] != RSA_BLOCK_FIRST_OCTET ||
|
||||
buffer[1] != (unsigned char)RSA_BlockPublic) {
|
||||
goto loser;
|
||||
if (inputLen != modulusLen || modulusLen < 10) {
|
||||
return SECFailure;
|
||||
}
|
||||
*outputLen = 0;
|
||||
for (i = 2; i < modulusLen; i++) {
|
||||
if (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
|
||||
*outputLen = modulusLen - i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*outputLen == 0)
|
||||
goto loser;
|
||||
if (*outputLen > maxOutputLen)
|
||||
goto loser;
|
||||
|
||||
PORT_Memcpy(output, buffer + modulusLen - *outputLen, *outputLen);
|
||||
if (copyOutLen > maxOutputLen) {
|
||||
copyOutLen = maxOutputLen;
|
||||
}
|
||||
|
||||
// Allocate enough space to decrypt + copyOutLen to allow copying outLen later.
|
||||
buffer = PORT_ZAlloc(modulusLen + 1 + copyOutLen);
|
||||
if (!buffer) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
// rv is 0 if everything is going well and 1 if an error occurs.
|
||||
rv = RSA_PrivateKeyOp(key, buffer, input) != SECSuccess;
|
||||
rv |= (buffer[0] != RSA_BLOCK_FIRST_OCTET) |
|
||||
(buffer[1] != (unsigned char)RSA_BlockPublic);
|
||||
|
||||
// There have to be at least 8 bytes of padding.
|
||||
for (i = 2; i < 10; i++) {
|
||||
rv |= buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET;
|
||||
}
|
||||
|
||||
for (i = 10; i < modulusLen; i++) {
|
||||
unsigned int newLen = modulusLen - i - 1;
|
||||
unsigned int c = (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) & (outLen == 0);
|
||||
outLen = constantTimeCondition(c, newLen, outLen);
|
||||
}
|
||||
rv |= outLen == 0;
|
||||
rv |= outLen > maxOutputLen;
|
||||
|
||||
// Note that output is set even if SECFailure is returned.
|
||||
PORT_Memcpy(output, buffer + modulusLen - outLen, copyOutLen);
|
||||
*outputLen = constantTimeCondition(outLen > maxOutputLen, maxOutputLen,
|
||||
outLen);
|
||||
|
||||
PORT_Free(buffer);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
PORT_Free(buffer);
|
||||
failure:
|
||||
return SECFailure;
|
||||
for (i = 1; i < sizeof(rv) * 8; i <<= 1) {
|
||||
rv |= rv << i;
|
||||
}
|
||||
return (SECStatus)rv;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -67,11 +67,11 @@ static const PRUint32 H256[8] = {
|
||||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||
};
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
#if (_MSC_VER >= 1300)
|
||||
#include <stdlib.h>
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#define SHA_HTONL(x) _byteswap_ulong(x)
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
#elif defined(_MSC_VER) && defined(NSS_X86_OR_X64)
|
||||
#ifndef FORCEINLINE
|
||||
#if (_MSC_VER >= 1200)
|
||||
@ -92,7 +92,6 @@ swap4b(PRUint32 dwd)
|
||||
}
|
||||
|
||||
#define SHA_HTONL(x) swap4b(x)
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
|
||||
#elif defined(__GNUC__) && defined(NSS_X86_OR_X64)
|
||||
static __inline__ PRUint32 swap4b(PRUint32 value)
|
||||
@ -101,7 +100,6 @@ static __inline__ PRUint32 swap4b(PRUint32 value)
|
||||
return (value);
|
||||
}
|
||||
#define SHA_HTONL(x) swap4b(x)
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__thumb2__) || \
|
||||
(!defined(__thumb__) && \
|
||||
@ -121,14 +119,14 @@ static __inline__ PRUint32 swap4b(PRUint32 value)
|
||||
return ret;
|
||||
}
|
||||
#define SHA_HTONL(x) swap4b(x)
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
|
||||
#else
|
||||
#define SWAP4MASK 0x00FF00FF
|
||||
#define SHA_HTONL(x) (t1 = (x), t1 = (t1 << 16) | (t1 >> 16), \
|
||||
((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK))
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
#endif
|
||||
#define BYTESWAP4(x) x = SHA_HTONL(x)
|
||||
#endif /* defined(IS_LITTLE_ENDIAN) */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma intrinsic (_lrotr, _lrotl)
|
||||
@ -665,6 +663,7 @@ void SHA224_Clone(SHA224Context *dest, SHA224Context *src)
|
||||
#define ULLC(hi,lo) 0x ## hi ## lo ## ULL
|
||||
#endif
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define SHA_HTONLL(x) _byteswap_uint64(x)
|
||||
@ -686,19 +685,20 @@ static __inline__ PRUint64 swap8b(PRUint64 value)
|
||||
(t1 >> 32) | (t1 << 32))
|
||||
#endif
|
||||
#define BYTESWAP8(x) x = SHA_HTONLL(x)
|
||||
#endif /* defined(IS_LITTLE_ENDIAN) */
|
||||
|
||||
#else /* no long long */
|
||||
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
#define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U }
|
||||
#else
|
||||
#define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
|
||||
#endif
|
||||
|
||||
#define SHA_HTONLL(x) ( BYTESWAP4(x.lo), BYTESWAP4(x.hi), \
|
||||
x.hi ^= x.lo ^= x.hi ^= x.lo, x)
|
||||
#define BYTESWAP8(x) do { PRUint32 tmp; BYTESWAP4(x.lo); BYTESWAP4(x.hi); \
|
||||
tmp = x.lo; x.lo = x.hi; x.hi = tmp; } while (0)
|
||||
#else
|
||||
#define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* SHA-384 and SHA-512 constants, K512. */
|
||||
|
@ -76,7 +76,7 @@ dostime(char *time, const char *s);
|
||||
|
||||
#ifdef NSS_X86_OR_X64
|
||||
/* The following macros throw up warnings. */
|
||||
#ifdef __GNUC__
|
||||
#if defined(__GNUC__) && !defined(NSS_NO_GCC48)
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
#define x86ShortToUint32(ii) ((const PRUint32)*((const PRUint16 *)(ii)))
|
||||
|
@ -49,8 +49,15 @@ JAR_calculate_digest(void *data, long length)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
md5 = PK11_CreateDigestContext(SEC_OID_MD5);
|
||||
md5 = PK11_CreateDigestContext(SEC_OID_MD5);
|
||||
if (md5 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sha1 = PK11_CreateDigestContext(SEC_OID_SHA1);
|
||||
if (sha1 == NULL) {
|
||||
PK11_DestroyContext(md5, PR_TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (length >= 0) {
|
||||
PK11_DigestBegin (md5);
|
||||
@ -107,6 +114,12 @@ JAR_digest_file (char *filename, JAR_Digest *dig)
|
||||
sha1 = PK11_CreateDigestContext (SEC_OID_SHA1);
|
||||
|
||||
if (md5 == NULL || sha1 == NULL) {
|
||||
if (md5) {
|
||||
PK11_DestroyContext(md5, PR_TRUE);
|
||||
}
|
||||
if (sha1) {
|
||||
PK11_DestroyContext(sha1, PR_TRUE);
|
||||
}
|
||||
/* can't generate digest contexts */
|
||||
PORT_Free (buf);
|
||||
JAR_FCLOSE (fp);
|
||||
|
@ -65,12 +65,10 @@ extern "C" {
|
||||
* FUNCTION: PKIX_RevocationChecker_Create
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Creates revocation checker object with a given flags.
|
||||
* Creates a revocation checker object with the given flags. Revocation will
|
||||
* be checked at the current date.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* "revDate"
|
||||
* Revocation will be checked at this date. Current date is taken if the
|
||||
* parameter is not specified.
|
||||
* "leafMethodListFlags"
|
||||
* Defines a set of method independent flags that will be used to check
|
||||
* revocation of the leaf cert in the chain.
|
||||
|
@ -359,7 +359,7 @@ pkix_pl_LdapDefaultClient_VerifyBindResponse(
|
||||
"pkix_pl_LdapDefaultClient_VerifyBindResponse");
|
||||
PKIX_NULLCHECK_TWO(client, client->rcvBuf);
|
||||
|
||||
decode.data = (void *)(client->rcvBuf);
|
||||
decode.data = (unsigned char *)(client->rcvBuf);
|
||||
decode.len = bufLen;
|
||||
|
||||
PKIX_CHECK(pkix_pl_LdapDefaultClient_DecodeBindResponse
|
||||
|
@ -730,7 +730,7 @@ pkix_pl_LdapResponse_GetResultCode(
|
||||
|
||||
resultMsg = &response->decoded.protocolOp.op.searchResponseResultMsg;
|
||||
|
||||
*pResultCode = *(char *)(resultMsg->resultCode.data);
|
||||
*pResultCode = *(resultMsg->resultCode.data);
|
||||
|
||||
cleanup:
|
||||
|
||||
|
@ -600,7 +600,7 @@ PKIX_PL_Object_Alloc(
|
||||
object = NULL;
|
||||
|
||||
/* Atomically increment object counter */
|
||||
PR_ATOMIC_INCREMENT(&ctEntry->objCounter);
|
||||
PR_ATOMIC_INCREMENT((PRInt32*)&ctEntry->objCounter);
|
||||
|
||||
cleanup:
|
||||
|
||||
@ -897,7 +897,7 @@ PKIX_PL_Object_DecRef(
|
||||
}
|
||||
|
||||
/* Atomically decrement object counter */
|
||||
PR_ATOMIC_DECREMENT(&ctEntry->objCounter);
|
||||
PR_ATOMIC_DECREMENT((PRInt32*)&ctEntry->objCounter);
|
||||
|
||||
/* pkix_pl_Object_Destroy assumes the lock is held */
|
||||
/* It will call unlock and destroy the object */
|
||||
|
@ -26,7 +26,7 @@ DIRS = \
|
||||
libpkix \
|
||||
certdb certhigh pk11wrap cryptohi nss \
|
||||
$(ZLIB_SRCDIR) ssl \
|
||||
pkcs12 pkcs7 smime \
|
||||
pkcs7 pkcs12 smime \
|
||||
crmf jar \
|
||||
ckfw $(SYSINIT_SRCDIR) \
|
||||
$(NULL)
|
||||
|
@ -6,6 +6,7 @@ CORE_DEPTH = ../..
|
||||
|
||||
PRIVATE_EXPORTS = \
|
||||
nssrenam.h \
|
||||
nssoptions.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
@ -16,6 +17,7 @@ MODULE = nss
|
||||
|
||||
CSRCS = \
|
||||
nssinit.c \
|
||||
nssoptions.c \
|
||||
nssver.c \
|
||||
utilwrap.c \
|
||||
$(NULL)
|
||||
|
@ -1082,3 +1082,11 @@ SECKEY_BigIntegerBitLength;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
;+NSS_3.21 { # NSS 3.21 release
|
||||
;+ global:
|
||||
NSS_OptionGet;
|
||||
NSS_OptionSet;
|
||||
SECMOD_CreateModuleEx;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
|
@ -26,6 +26,9 @@
|
||||
#define _NSS_CUSTOMIZED
|
||||
#endif
|
||||
|
||||
#undef _NSS_CUSTOMIZED
|
||||
#define _NSS_CUSTOMIZED " (RetroZilla)"
|
||||
|
||||
/*
|
||||
* NSS's major version, minor version, patch level, build number, and whether
|
||||
* this is a beta release.
|
||||
@ -33,11 +36,11 @@
|
||||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define NSS_VERSION "3.20.0.1" _NSS_ECC_STRING _NSS_CUSTOMIZED
|
||||
#define NSS_VERSION "3.21.4" _NSS_ECC_STRING _NSS_CUSTOMIZED
|
||||
#define NSS_VMAJOR 3
|
||||
#define NSS_VMINOR 20
|
||||
#define NSS_VPATCH 0
|
||||
#define NSS_VBUILD 1
|
||||
#define NSS_VMINOR 21
|
||||
#define NSS_VPATCH 4
|
||||
#define NSS_VBUILD 0
|
||||
#define NSS_BETA PR_FALSE
|
||||
|
||||
#ifndef RC_INVOKED
|
||||
@ -294,6 +297,19 @@ SECStatus NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData);
|
||||
*/
|
||||
SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData);
|
||||
|
||||
/* Available options for NSS_OptionSet() and NSS_OptionGet().
|
||||
*/
|
||||
#define NSS_RSA_MIN_KEY_SIZE (1<<0)
|
||||
#define NSS_DH_MIN_KEY_SIZE (1<<1)
|
||||
#define NSS_DSA_MIN_KEY_SIZE (1<<2)
|
||||
|
||||
/*
|
||||
* Set and get global options for the NSS library.
|
||||
*/
|
||||
SECStatus NSS_OptionSet(PRInt32 which, PRInt32 value);
|
||||
SECStatus NSS_OptionGet(PRInt32 which, PRInt32 *value);
|
||||
|
||||
|
||||
/*
|
||||
* Close the Cert, Key databases.
|
||||
*/
|
||||
|
73
security/nss/lib/nss/nssoptions.c
Normal file
73
security/nss/lib/nss/nssoptions.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* NSS utility functions
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secoidt.h"
|
||||
#include "secoid.h"
|
||||
#include "nss.h"
|
||||
#include "nssoptions.h"
|
||||
|
||||
struct nssOps {
|
||||
PRInt32 rsaMinKeySize;
|
||||
PRInt32 dhMinKeySize;
|
||||
PRInt32 dsaMinKeySize;
|
||||
};
|
||||
|
||||
static struct nssOps nss_ops = {
|
||||
SSL_RSA_MIN_MODULUS_BITS,
|
||||
SSL_DH_MIN_P_BITS,
|
||||
SSL_DSA_MIN_P_BITS
|
||||
};
|
||||
|
||||
SECStatus
|
||||
NSS_OptionSet(PRInt32 which, PRInt32 value)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
switch (which) {
|
||||
case NSS_RSA_MIN_KEY_SIZE:
|
||||
nss_ops.rsaMinKeySize = value;
|
||||
break;
|
||||
case NSS_DH_MIN_KEY_SIZE:
|
||||
nss_ops.dhMinKeySize = value;
|
||||
break;
|
||||
case NSS_DSA_MIN_KEY_SIZE:
|
||||
nss_ops.dsaMinKeySize = value;
|
||||
break;
|
||||
default:
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
NSS_OptionGet(PRInt32 which, PRInt32 *value)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
switch (which) {
|
||||
case NSS_RSA_MIN_KEY_SIZE:
|
||||
*value = nss_ops.rsaMinKeySize;
|
||||
break;
|
||||
case NSS_DH_MIN_KEY_SIZE:
|
||||
*value = nss_ops.dhMinKeySize;
|
||||
break;
|
||||
case NSS_DSA_MIN_KEY_SIZE:
|
||||
*value = nss_ops.dsaMinKeySize;
|
||||
break;
|
||||
default:
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
21
security/nss/lib/nss/nssoptions.h
Normal file
21
security/nss/lib/nss/nssoptions.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* NSS utility functions
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* Include the default limits here
|
||||
*/
|
||||
/* SSL default limits are here so we don't have to import a private SSL header
|
||||
* file into NSS proper */
|
||||
|
||||
/* The minimum server key sizes accepted by the clients.
|
||||
* Not 1024 to be conservative. */
|
||||
#define SSL_RSA_MIN_MODULUS_BITS 1023
|
||||
/* 1023 to avoid cases where p = 2q+1 for a 512-bit q turns out to be
|
||||
* only 1023 bits and similar. We don't have good data on whether this
|
||||
* happens because NSS used to count bit lengths incorrectly. */
|
||||
#define SSL_DH_MIN_P_BITS 1023
|
||||
#define SSL_DSA_MIN_P_BITS 1023
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "secasn1.h"
|
||||
#include "secoid.h"
|
||||
#include "secerr.h"
|
||||
#include "sslerr.h"
|
||||
#include "sechash.h"
|
||||
|
||||
#include "secpkcs5.h"
|
||||
@ -74,7 +73,7 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
|
||||
SECItem *ckaId = NULL;
|
||||
SECItem *pubValue = NULL;
|
||||
int signedcount = 0;
|
||||
int templateCount = 0;
|
||||
unsigned int templateCount = 0;
|
||||
SECStatus rv;
|
||||
|
||||
/* if we already have an object in the desired slot, use it */
|
||||
@ -165,7 +164,6 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
|
||||
keyType = CKK_EC;
|
||||
PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++;
|
||||
signedattr = attrs;
|
||||
PK11_SETATTRS(attrs, CKA_EC_PARAMS,
|
||||
pubKey->u.ec.DEREncodedParams.data,
|
||||
pubKey->u.ec.DEREncodedParams.len); attrs++;
|
||||
@ -196,10 +194,14 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
|
||||
}
|
||||
|
||||
templateCount = attrs - theTemplate;
|
||||
signedcount = attrs - signedattr;
|
||||
PORT_Assert(templateCount <= (sizeof(theTemplate)/sizeof(CK_ATTRIBUTE)));
|
||||
for (attrs=signedattr; signedcount; attrs++, signedcount--) {
|
||||
pk11_SignedToUnsigned(attrs);
|
||||
|
||||
if (pubKey->keyType != ecKey) {
|
||||
PORT_Assert(signedattr);
|
||||
signedcount = attrs - signedattr;
|
||||
for (attrs = signedattr; signedcount; attrs++, signedcount--) {
|
||||
pk11_SignedToUnsigned(attrs);
|
||||
}
|
||||
}
|
||||
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate,
|
||||
templateCount, isToken, &objectID);
|
||||
@ -403,7 +405,7 @@ pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams,
|
||||
/* If the point is uncompressed and the lengths match, it
|
||||
* must be an unencoded point */
|
||||
if ((*((char *)ecPoint->pValue) == EC_POINT_FORM_UNCOMPRESSED)
|
||||
&& (ecPoint->ulValueLen == keyLen)) {
|
||||
&& (ecPoint->ulValueLen == (unsigned int)keyLen)) {
|
||||
return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue);
|
||||
}
|
||||
|
||||
@ -417,7 +419,7 @@ pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams,
|
||||
|
||||
/* it coded correctly & we know the key length (and they match)
|
||||
* then we are done, return the results. */
|
||||
if (keyLen && rv == SECSuccess && publicKeyValue->len == keyLen) {
|
||||
if (keyLen && rv == SECSuccess && publicKeyValue->len == (unsigned int)keyLen) {
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
@ -549,7 +551,7 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
|
||||
PLArenaPool *arena;
|
||||
PLArenaPool *tmp_arena;
|
||||
SECKEYPublicKey *pubKey;
|
||||
int templateCount = 0;
|
||||
unsigned int templateCount = 0;
|
||||
CK_KEY_TYPE pk11KeyType;
|
||||
CK_RV crv;
|
||||
CK_ATTRIBUTE template[8];
|
||||
@ -957,9 +959,13 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
|
||||
&cktrue, &ckfalse);
|
||||
|
||||
/* Not everyone can handle zero padded key values, give
|
||||
* them the raw data as unsigned */
|
||||
for (ap=attrs; extra_count; ap++, extra_count--) {
|
||||
pk11_SignedToUnsigned(ap);
|
||||
* them the raw data as unsigned. The exception is EC,
|
||||
* where the values are encoded or zero-preserving
|
||||
* per-RFC5915 */
|
||||
if (privKey->keyType != ecKey) {
|
||||
for (ap = attrs; extra_count; ap++, extra_count--) {
|
||||
pk11_SignedToUnsigned(ap);
|
||||
}
|
||||
}
|
||||
|
||||
/* now Store the puppies */
|
||||
@ -1516,6 +1522,7 @@ PK11_MakeKEAPubKey(unsigned char *keyData,int length)
|
||||
|
||||
pkData.data = keyData;
|
||||
pkData.len = length;
|
||||
pkData.type = siBuffer;
|
||||
|
||||
arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
|
||||
if (arena == NULL)
|
||||
@ -2308,7 +2315,7 @@ PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname)
|
||||
CK_ATTRIBUTE *attrs;
|
||||
CK_BBOOL ckTrue = CK_TRUE;
|
||||
CK_OBJECT_CLASS keyclass = CKO_PUBLIC_KEY;
|
||||
int tsize = 0;
|
||||
unsigned int tsize = 0;
|
||||
int objCount = 0;
|
||||
CK_OBJECT_HANDLE *key_ids;
|
||||
SECKEYPublicKeyList *keys;
|
||||
@ -2354,7 +2361,7 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
|
||||
CK_ATTRIBUTE *attrs;
|
||||
CK_BBOOL ckTrue = CK_TRUE;
|
||||
CK_OBJECT_CLASS keyclass = CKO_PRIVATE_KEY;
|
||||
int tsize = 0;
|
||||
unsigned int tsize = 0;
|
||||
int objCount = 0;
|
||||
CK_OBJECT_HANDLE *key_ids;
|
||||
SECKEYPrivateKeyList *keys;
|
||||
|
@ -172,7 +172,9 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
||||
SECKEY_DestroyPublicKey(pubKey);
|
||||
return PR_FALSE;
|
||||
}
|
||||
pk11_SignedToUnsigned(&theTemplate);
|
||||
if (pubKey->keyType != ecKey) {
|
||||
pk11_SignedToUnsigned(&theTemplate);
|
||||
}
|
||||
if (pk11_FindObjectByTemplate(slot,&theTemplate,1) != CK_INVALID_HANDLE) {
|
||||
SECKEY_DestroyPublicKey(pubKey);
|
||||
return PR_TRUE;
|
||||
@ -1381,6 +1383,7 @@ pk11_keyIDHash_populate(void *wincx)
|
||||
}
|
||||
moduleLock = SECMOD_GetDefaultModuleListLock();
|
||||
if (!moduleLock) {
|
||||
SECITEM_FreeItem(slotid, PR_TRUE);
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
@ -1440,6 +1443,7 @@ pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipien
|
||||
sizeof(CK_SLOT_ID) + sizeof(SECMODModuleID));
|
||||
if (!slotid) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
PK11_FreeSlotList(sl);
|
||||
return NULL;
|
||||
}
|
||||
for (le = sl->head; le; le = le->next) {
|
||||
|
@ -152,6 +152,8 @@ PK11_GetKeyMechanism(CK_KEY_TYPE type)
|
||||
return CKM_SEED_CBC;
|
||||
case CKK_CAMELLIA:
|
||||
return CKM_CAMELLIA_CBC;
|
||||
case CKK_NSS_CHACHA20:
|
||||
return CKM_NSS_CHACHA20_POLY1305;
|
||||
case CKK_AES:
|
||||
return CKM_AES_CBC;
|
||||
case CKK_DES:
|
||||
@ -220,6 +222,9 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
|
||||
case CKM_CAMELLIA_KEY_GEN:
|
||||
case CKM_CAMELLIA_GCM:
|
||||
return CKK_CAMELLIA;
|
||||
case CKM_NSS_CHACHA20_POLY1305:
|
||||
case CKM_NSS_CHACHA20_KEY_GEN:
|
||||
return CKK_NSS_CHACHA20;
|
||||
case CKM_AES_ECB:
|
||||
case CKM_AES_CBC:
|
||||
case CKM_AES_CCM:
|
||||
@ -380,6 +385,8 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
|
||||
case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256:
|
||||
case CKM_TLS_KEY_AND_MAC_DERIVE:
|
||||
case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
|
||||
case CKM_SHA_1_HMAC:
|
||||
case CKM_SHA_1_HMAC_GENERAL:
|
||||
case CKM_SHA224_HMAC:
|
||||
@ -431,6 +438,8 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
|
||||
case CKM_CAMELLIA_KEY_GEN:
|
||||
case CKM_CAMELLIA_GCM:
|
||||
return CKM_CAMELLIA_KEY_GEN;
|
||||
case CKM_NSS_CHACHA20_POLY1305:
|
||||
return CKM_NSS_CHACHA20_KEY_GEN;
|
||||
case CKM_AES_ECB:
|
||||
case CKM_AES_CBC:
|
||||
case CKM_AES_CCM:
|
||||
@ -575,6 +584,8 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
|
||||
case CKM_TLS_MASTER_KEY_DERIVE:
|
||||
case CKM_TLS_KEY_AND_MAC_DERIVE:
|
||||
case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
|
||||
case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
|
||||
return CKM_SSL3_PRE_MASTER_KEY_GEN;
|
||||
case CKM_SHA_1_HMAC:
|
||||
case CKM_SHA_1_HMAC_GENERAL:
|
||||
|
@ -1261,7 +1261,8 @@ pk11_mergeByObjectIDs(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
|
||||
PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
int error, i;
|
||||
int error = SEC_ERROR_LIBRARY_FAILURE;
|
||||
int i;
|
||||
|
||||
for (i=0; i < count; i++) {
|
||||
/* try to update the entire database. On failure, keep going,
|
||||
@ -1325,7 +1326,8 @@ PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
|
||||
PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
|
||||
{
|
||||
SECStatus rv = SECSuccess, lrv = SECSuccess;
|
||||
int error, count = 0;
|
||||
int error = SEC_ERROR_LIBRARY_FAILURE;
|
||||
int count = 0;
|
||||
CK_ATTRIBUTE search[2];
|
||||
CK_OBJECT_HANDLE *objectIDs = NULL;
|
||||
CK_BBOOL ck_true = CK_TRUE;
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include "certdb.h"
|
||||
#include "secerr.h"
|
||||
#include "sslerr.h"
|
||||
|
||||
#include "pki3hack.h"
|
||||
#include "dev3hack.h"
|
||||
|
@ -1577,7 +1577,7 @@ PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,
|
||||
CK_ATTRIBUTE_TYPE attrType, SECItem *item)
|
||||
{
|
||||
PK11SlotInfo *slot = NULL;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
CK_OBJECT_HANDLE handle = 0;
|
||||
CK_ATTRIBUTE setTemplate;
|
||||
CK_RV crv;
|
||||
CK_SESSION_HANDLE rwsession;
|
||||
@ -1630,7 +1630,7 @@ PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec,
|
||||
CK_ATTRIBUTE_TYPE attrType, SECItem *item)
|
||||
{
|
||||
PK11SlotInfo *slot = NULL;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
CK_OBJECT_HANDLE handle = 0;
|
||||
|
||||
switch (objType) {
|
||||
case PK11_TypeGeneric:
|
||||
|
@ -133,6 +133,17 @@ secmod_NewModule(void)
|
||||
SECMODModule *
|
||||
SECMOD_CreateModule(const char *library, const char *moduleName,
|
||||
const char *parameters, const char *nss)
|
||||
{
|
||||
return SECMOD_CreateModuleEx(library, moduleName, parameters, nss, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* for 3.4 we continue to use the old SECMODModule structure
|
||||
*/
|
||||
SECMODModule *
|
||||
SECMOD_CreateModuleEx(const char *library, const char *moduleName,
|
||||
const char *parameters, const char *nss,
|
||||
const char *config)
|
||||
{
|
||||
SECMODModule *mod = secmod_NewModule();
|
||||
char *slotParams,*ciphers;
|
||||
@ -148,6 +159,9 @@ SECMOD_CreateModule(const char *library, const char *moduleName,
|
||||
if (parameters) {
|
||||
mod->libraryParams = PORT_ArenaStrdup(mod->arena,parameters);
|
||||
}
|
||||
if (config) {
|
||||
/* XXX: Apply configuration */
|
||||
}
|
||||
mod->internal = NSSUTIL_ArgHasFlag("flags","internal",nssc);
|
||||
mod->isFIPS = NSSUTIL_ArgHasFlag("flags","FIPS",nssc);
|
||||
mod->isCritical = NSSUTIL_ArgHasFlag("flags","critical",nssc);
|
||||
@ -977,6 +991,7 @@ SECMODModule *
|
||||
SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse)
|
||||
{
|
||||
char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL;
|
||||
char *config = NULL;
|
||||
SECStatus status;
|
||||
SECMODModule *module = NULL;
|
||||
SECMODModule *oldModule = NULL;
|
||||
@ -985,17 +1000,19 @@ SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse)
|
||||
/* initialize the underlying module structures */
|
||||
SECMOD_Init();
|
||||
|
||||
status = NSSUTIL_ArgParseModuleSpec(modulespec, &library, &moduleName,
|
||||
¶meters, &nss);
|
||||
status = NSSUTIL_ArgParseModuleSpecEx(modulespec, &library, &moduleName,
|
||||
¶meters, &nss,
|
||||
&config);
|
||||
if (status != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
module = SECMOD_CreateModule(library, moduleName, parameters, nss);
|
||||
module = SECMOD_CreateModuleEx(library, moduleName, parameters, nss, config);
|
||||
if (library) PORT_Free(library);
|
||||
if (moduleName) PORT_Free(moduleName);
|
||||
if (parameters) PORT_Free(parameters);
|
||||
if (nss) PORT_Free(nss);
|
||||
if (config) PORT_Free(config);
|
||||
if (!module) {
|
||||
goto loser;
|
||||
}
|
||||
|
@ -234,13 +234,17 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
|
||||
rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate,
|
||||
derPKI);
|
||||
if( rv != SECSuccess ) {
|
||||
goto finish;
|
||||
/* If SEC_ASN1DecodeItem fails, we cannot assume anything about the
|
||||
* validity of the data in pki. The best we can do is free the arena
|
||||
* and return.
|
||||
*/
|
||||
PORT_FreeArena(temparena, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
|
||||
publicValue, isPerm, isPrivate, keyUsage, privk, wincx);
|
||||
|
||||
finish:
|
||||
/* this zeroes the key and frees the arena */
|
||||
SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/);
|
||||
return rv;
|
||||
@ -278,6 +282,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
|
||||
PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse,
|
||||
sizeof(CK_BBOOL) ); attrs++;
|
||||
|
||||
PORT_Assert(lpk->keyType != ecKey); /* see bug 1558548 if this is needed */
|
||||
switch (lpk->keyType) {
|
||||
case rsaKey:
|
||||
keyType = CKK_RSA;
|
||||
|
@ -400,6 +400,7 @@ PK11_NewSlotInfo(SECMODModule *mod)
|
||||
slot->minPassword = 0;
|
||||
slot->maxPassword = 0;
|
||||
slot->hasRootCerts = PR_FALSE;
|
||||
slot->hasRootTrust = PR_FALSE;
|
||||
slot->nssToken = NULL;
|
||||
return slot;
|
||||
}
|
||||
|
@ -64,6 +64,9 @@ SECStatus SECMOD_UnloadUserModule(SECMODModule *mod);
|
||||
|
||||
SECMODModule * SECMOD_CreateModule(const char *lib, const char *name,
|
||||
const char *param, const char *nss);
|
||||
SECMODModule * SECMOD_CreateModuleEx(const char *lib, const char *name,
|
||||
const char *param, const char *nss,
|
||||
const char *config);
|
||||
/*
|
||||
* After a fork(), PKCS #11 says we need to call C_Initialize again in
|
||||
* the child before we can use the module. This function causes this
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user