Merge pull request #38 from roytam1/nss-vc71-fix

Nss vc71 fix and more updates
This commit is contained in:
rn10950 2020-12-11 06:34:58 -05:00 committed by GitHub
commit 15b368a2fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
167 changed files with 10404 additions and 4847 deletions

View File

@ -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

View File

@ -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, &params->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) {

View File

@ -0,0 +1 @@
PQRSタチツテトナニヌ

View File

@ -0,0 +1 @@
0xqNNGSOYNt7hq+8U+9+wqSt7VEpbgj+qeK1pzbuYtY9vqRejKlnEoL6+2naknKLGnHeCp4GCykF1qW2fs07NpLdvX8td4uMmAOu4ygJG1j6syTk+tZ1lFWFgItIMde8P/Te8I5Lep3ldtJlhs7GS2EWGuELWU8J4mp+kC7L0GAGkQ==

View File

@ -0,0 +1 @@
ZKCGFXWGGvRg8GLHm+ZDvV6AXP00XPOJ8QhnCsdsjLJMbPwYdV1D7qCe6U44LSawvbe3PDIbAQDU8Dt/NViUzzMvgw5xC5fOmMioSr0LlIEUrRduAI0zvWD5grH/N8hVl5egbvTw72HBhjJOKzUGODYGkHtqfAKw+fYVe1PIZ+S5Fmx2e4BNRqWbUhbN56TpkEDFpAQzIl7igqGwoGxSPq9FNNf4P6EVWwBHcYy8VGoNBysEs1ZO6htCInP1SCcaC7IxYFP6dpkZVevWMVlDTs67TkZtrloQc6ZydicJehBJ5hfZHTYQlPpo8P93mHEwMFvqui7aBN+Ze3FNbG8sKaatXLQCKwJwm+6tnWeJDLsiOSM2/qGFHzg=

View File

@ -0,0 +1 @@
€≠ヤ<EFBFBD>㊧炎旧克署葬灯楓利劒屆撼<EFBFBD>

View File

@ -0,0 +1 @@
<1C>@<40><><55>3<EFBFBD><33><04><><EFBFBD>G9<17>@+<2B> <09><>\<5C> pu<70>

View File

@ -0,0 +1 @@
2

View File

@ -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.

View File

@ -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./”

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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);
}
/*************************************************************************/

View File

@ -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) {

View File

@ -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);

View File

@ -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");
}

View File

@ -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':

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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))

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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)))

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -171,6 +171,7 @@ nssCKFWObject_Create
if( CKR_OK == *pError ) {
*pError = CKR_GENERAL_ERROR;
}
nss_ZFreeIf(fwObject);
return (NSSCKFWObject *)NULL;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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;

View 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_ */

View 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

View File

@ -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);
}

View File

@ -911,7 +911,7 @@ hash_seq(
uint flag)
{
register uint32 bucket;
register BUFHEAD *bufp;
register BUFHEAD *bufp = NULL;
HTAB *hashp;
uint16 *bp, ndx;

View File

@ -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++) {

View File

@ -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 \

View File

@ -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.

View File

@ -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

View 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];
}
}
}

View 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_ */

View 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];
}
}
}

View 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;
}

View 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_ */

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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.

View File

@ -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;
}

View File

@ -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)

View 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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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: 549553 (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 */

View File

@ -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 *

View File

@ -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);
}

View File

@ -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. */
};

View 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 \

View File

@ -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() */
/* }}} */

View File

@ -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)

View File

@ -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

View File

@ -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)));
}

View 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);
}

View 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_ */

View File

@ -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;

View File

@ -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;
}
/*

View File

@ -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. */

View File

@ -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)))

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -730,7 +730,7 @@ pkix_pl_LdapResponse_GetResultCode(
resultMsg = &response->decoded.protocolOp.op.searchResponseResultMsg;
*pResultCode = *(char *)(resultMsg->resultCode.data);
*pResultCode = *(resultMsg->resultCode.data);
cleanup:

View File

@ -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 */

View File

@ -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)

View File

@ -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)

View File

@ -1082,3 +1082,11 @@ SECKEY_BigIntegerBitLength;
;+ local:
;+ *;
;+};
;+NSS_3.21 { # NSS 3.21 release
;+ global:
NSS_OptionGet;
NSS_OptionSet;
SECMOD_CreateModuleEx;
;+ local:
;+ *;
;+};

View File

@ -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.
*/

View 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;
}

View 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

View File

@ -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;

View File

@ -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) {

View File

@ -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:

View File

@ -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;

View File

@ -21,7 +21,6 @@
#include "certdb.h"
#include "secerr.h"
#include "sslerr.h"
#include "pki3hack.h"
#include "dev3hack.h"

View File

@ -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:

View File

@ -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,
&parameters, &nss);
status = NSSUTIL_ArgParseModuleSpecEx(modulespec, &library, &moduleName,
&parameters, &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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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