static void sftk_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data, unsigned int data_len) { PRUint32 bytesUsed = cx->cxKeyLen + cx->cxDataLen; if (cx->cxRv != SECSuccess) /* function has previously failed. */ return; if (bytesUsed + data_len > cx->cxBufSize) { /* We don't use realloc here because ** (a) realloc doesn't zero out the old block, and ** (b) if realloc fails, we lose the old block. */ PRUint32 newBufSize = bytesUsed + data_len + 512; unsigned char * newBuf = (unsigned char *)PORT_Alloc(newBufSize); if (!newBuf) { cx->cxRv = SECFailure; return; } PORT_Memcpy(newBuf, cx->cxBufPtr, bytesUsed); if (cx->cxBufPtr != cx->cxBuf) { PORT_ZFree(cx->cxBufPtr, bytesUsed); } cx->cxBufPtr = newBuf; cx->cxBufSize = newBufSize; } PORT_Memcpy(cx->cxBufPtr + bytesUsed, data, data_len); cx->cxDataLen += data_len; }
/* If key is not NULL then the gx value will be stored as an attribute with the type given by the gxAttrType parameter. */ static CK_RV jpake_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType, const SECItem * signerID, const SECItem * x, CK_NSS_JPAKEPublicValue * out) { SECItem gx, gv, r; CK_RV crv; PORT_Assert(arena != NULL); gx.data = NULL; gv.data = NULL; r.data = NULL; crv = jpake_mapStatus(JPAKE_Sign(arena, pqg, hashType, signerID, x, NULL, NULL, &gx, &gv, &r), CKR_MECHANISM_PARAM_INVALID); if (crv == CKR_OK) { if ((out->pGX != NULL && out->ulGXLen >= gx.len) || (out->pGV != NULL && out->ulGVLen >= gv.len) || (out->pR != NULL && out->ulRLen >= r.len)) { PORT_Memcpy(out->pGX, gx.data, gx.len); PORT_Memcpy(out->pGV, gv.data, gv.len); PORT_Memcpy(out->pR, r.data, r.len); out->ulGXLen = gx.len; out->ulGVLen = gv.len; out->ulRLen = r.len; } else { crv = CKR_MECHANISM_PARAM_INVALID; } } return crv; }
SECItem * SSL_GetSessionID(PRFileDesc *fd) { sslSocket * ss; SECItem * item = NULL; ss = ssl_FindSocket(fd); if (ss) { ssl_Get1stHandshakeLock(ss); ssl_GetSSL3HandshakeLock(ss); if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) { item = (SECItem *)PORT_Alloc(sizeof(SECItem)); if (item) { sslSessionID * sid = ss->sec.ci.sid; if (sid->version < SSL_LIBRARY_VERSION_3_0) { item->len = SSL2_SESSIONID_BYTES; item->data = (unsigned char*)PORT_Alloc(item->len); PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len); } else { item->len = sid->u.ssl3.sessionIDLength; item->data = (unsigned char*)PORT_Alloc(item->len); PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len); } } } ssl_ReleaseSSL3HandshakeLock(ss); ssl_Release1stHandshakeLock(ss); } return item; }
static PRLibrary * sftkdb_LoadFromPath(const char *path, const char *libname) { char *c; int pathLen, nameLen, fullPathLen; char *fullPathName = NULL; PRLibSpec libSpec; PRLibrary *lib = NULL; /* strip of our parent's library name */ c = strrchr(path, PR_GetDirectorySeparator()); if (!c) { return NULL; /* invalid path */ } pathLen = (c-path)+1; nameLen = strlen(libname); fullPathLen = pathLen + nameLen +1; fullPathName = (char *)PORT_Alloc(fullPathLen); if (fullPathName == NULL) { return NULL; /* memory allocation error */ } PORT_Memcpy(fullPathName, path, pathLen); PORT_Memcpy(fullPathName+pathLen, libname, nameLen); fullPathName[fullPathLen-1] = 0; libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = fullPathName; lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); PORT_Free(fullPathName); return lib; }
/* * copy desc and value into target. Target is known to be big enough to * hold desc +2 +value, which is good because the result of this will be * *desc"*value". We may, however, have to add some escapes for special * characters imbedded into value (rare). This string potentially comes from * a user, so we don't want the user overflowing the target buffer by using * excessive escapes. To prevent this we count the escapes we need to add and * try to expand the buffer with Realloc. */ static char * secmod_doDescCopy(char *target, int *targetLen, const char *desc, int descLen, char *value) { int diff, esc_len; esc_len = NSSUTIL_EscapeSize(value, '\"') - 1; diff = esc_len - strlen(value); if (diff > 0) { /* we need to escape... expand newSpecPtr as well to make sure * we don't overflow it */ char *newPtr = PORT_Realloc(target, *targetLen * diff); if (!newPtr) { return target; /* not enough space, just drop the whole copy */ } *targetLen += diff; target = newPtr; value = NSSUTIL_Escape(value, '\"'); if (value == NULL) { return target; /* couldn't escape value, just drop the copy */ } } PORT_Memcpy(target, desc, descLen); target += descLen; *target++='\"'; PORT_Memcpy(target, value, esc_len); target += esc_len; *target++='\"'; if (diff > 0) { PORT_Free(value); } return target; }
/* * This function expands the internal state of the prng to fulfill any number * of bytes we need for this request. We only use this call if we need more * than can be supplied by a single call to SHA256_HashBuf. * * This function is specified in NIST SP 800-90 section 10.1.1.4, Hashgen */ static void prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes, unsigned int no_of_returned_bytes) { PRUint8 data[VSize(rng)]; PRUint8 thisHash[SHA256_LENGTH]; PORT_Memcpy(data, V(rng), VSize(rng)); while (no_of_returned_bytes) { SHA256Context ctx; unsigned int len; unsigned int carry; SHA256_Begin(&ctx); SHA256_Update(&ctx, data, sizeof data); SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH); if (no_of_returned_bytes < SHA256_LENGTH) { len = no_of_returned_bytes; } PORT_Memcpy(returned_bytes, thisHash, len); returned_bytes += len; no_of_returned_bytes -= len; /* The carry parameter is a bool (increment or not). * This increments data if no_of_returned_bytes is not zero */ carry = no_of_returned_bytes; PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry); } PORT_Memset(data, 0, sizeof data); PORT_Memset(thisHash, 0, sizeof thisHash); }
/* create a virtual password per PKCS 12, the password is converted * to unicode, the salt is prepended to it, and then the whole thing * is returned */ SECItem * sec_pkcs12_create_virtual_password(SECItem *password, SECItem *salt, PRBool swap) { SECItem uniPwd = {siBuffer, NULL,0}, *retPwd = NULL; if((password == NULL) || (salt == NULL)) { return NULL; } if(password->len == 0) { uniPwd.data = (unsigned char*)PORT_ZAlloc(2); uniPwd.len = 2; if(!uniPwd.data) { return NULL; } } else { uniPwd.data = (unsigned char*)PORT_ZAlloc(password->len * 3); uniPwd.len = password->len * 3; if(!PORT_UCS2_ASCIIConversion(PR_TRUE, password->data, password->len, uniPwd.data, uniPwd.len, &uniPwd.len, swap)) { SECITEM_ZfreeItem(&uniPwd, PR_FALSE); return NULL; } } retPwd = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); if(retPwd == NULL) { goto loser; } /* allocate space and copy proper data */ retPwd->len = uniPwd.len + salt->len; retPwd->data = (unsigned char *)PORT_Alloc(retPwd->len); if(retPwd->data == NULL) { PORT_Free(retPwd); goto loser; } PORT_Memcpy(retPwd->data, salt->data, salt->len); PORT_Memcpy((retPwd->data + salt->len), uniPwd.data, uniPwd.len); SECITEM_ZfreeItem(&uniPwd, PR_FALSE); return retPwd; loser: PORT_SetError(SEC_ERROR_NO_MEMORY); SECITEM_ZfreeItem(&uniPwd, PR_FALSE); return NULL; }
/* Use this function to update the ClientRandom of a client's handshake state * after replacing its ClientHello message. We for example need to do this * when replacing an SSLv3 ClientHello with its SSLv2 equivalent. */ SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd, size_t rnd_len, uint8_t *msg, size_t msg_len) { sslSocket *ss = ssl_FindSocket(fd); if (!ss) { return SECFailure; } SECStatus rv = ssl3_InitState(ss); if (rv != SECSuccess) { return rv; } rv = ssl3_RestartHandshakeHashes(ss); if (rv != SECSuccess) { return rv; } // Zero the client_random struct. PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH); // Copy over the challenge bytes. size_t offset = SSL3_RANDOM_LENGTH - rnd_len; PORT_Memcpy(&ss->ssl3.hs.client_random.rand[offset], rnd, rnd_len); // Rehash the SSLv2 client hello message. return ssl3_UpdateHandshakeHashes(ss, msg, msg_len); }
NS_IMETHODIMP nsNSSCertificateFakeTransport::Read(nsIObjectInputStream* aStream) { PRUint32 len; nsresult rv = aStream->Read32(&len); if (NS_FAILED(rv)) { return rv; } nsXPIDLCString str; rv = aStream->ReadBytes(len, getter_Copies(str)); if (NS_FAILED(rv)) { return rv; } // On a non-chrome process we cannot instatiate mCert because we lack // nsNSSComponent. nsNSSCertificateFakeTransport object is used only to carry the // certificate serialization. mCertSerialization = SECITEM_AllocItem(nsnull, nsnull, len); if (!mCertSerialization) return NS_ERROR_OUT_OF_MEMORY; PORT_Memcpy(mCertSerialization->data, str.Data(), len); return NS_OK; }
/* * See addemdum to NIST SP 800-38A * Generically handle cipher text stealing. Basically this is doing CBC * operations except someone can pass us a partial block. * * Output Order: * CS-1: C1||C2||C3..Cn-1(could be partial)||Cn (NIST) * CS-2: pad == 0 C1||C2||C3...Cn-1(is full)||Cn (Schneier) * CS-2: pad != 0 C1||C2||C3...Cn||Cn-1(is partial)(Schneier) * CS-3: C1||C2||C3...Cn||Cn-1(could be partial) (Kerberos) * * The characteristics of these three options: * - NIST & Schneier (CS-1 & CS-2) are identical to CBC if there are no * partial blocks on input. * - Scheier and Kerberos (CS-2 and CS-3) have no embedded partial blocks, * which make decoding easier. * - NIST & Kerberos (CS-1 and CS-3) have consistent block order independent * of padding. * * PKCS #11 did not specify which version to implement, but points to the NIST * spec, so this code implements CTS-CS-1 from NIST. * * To convert the returned buffer to: * CS-2 (Schneier): do * unsigned char tmp[MAX_BLOCK_SIZE]; * pad = *outlen % blocksize; * if (pad) { * memcpy(tmp, outbuf+*outlen-blocksize, blocksize); * memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad); * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize); * } * CS-3 (Kerberos): do * unsigned char tmp[MAX_BLOCK_SIZE]; * pad = *outlen % blocksize; * if (pad == 0) { * pad = blocksize; * } * memcpy(tmp, outbuf+*outlen-blocksize, blocksize); * memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad); * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize); */ SECStatus CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf, unsigned int *outlen, unsigned int maxout, const unsigned char *inbuf, unsigned int inlen, unsigned int blocksize) { unsigned char lastBlock[MAX_BLOCK_SIZE]; unsigned int tmp; int fullblocks; int written; unsigned char *saveout = outbuf; SECStatus rv; if (inlen < blocksize) { PORT_SetError(SEC_ERROR_INPUT_LEN); return SECFailure; } if (maxout < inlen) { *outlen = inlen; PORT_SetError(SEC_ERROR_OUTPUT_LEN); return SECFailure; } fullblocks = (inlen / blocksize) * blocksize; rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf, fullblocks, blocksize); if (rv != SECSuccess) { return SECFailure; } *outlen = fullblocks; /* AES low level doesn't set outlen */ inbuf += fullblocks; inlen -= fullblocks; if (inlen == 0) { return SECSuccess; } written = *outlen - (blocksize - inlen); outbuf += written; maxout -= written; /* * here's the CTS magic, we pad our final block with zeros, * then do a CBC encrypt. CBC will xor our plain text with * the previous block (Cn-1), capturing part of that block (Cn-1**) as it * xors with the zero pad. We then write this full block, overwritting * (Cn-1**) in our buffer. This allows us to have input data == output * data since Cn contains enough information to reconver Cn-1** when * we decrypt (at the cost of some complexity as you can see in decrypt * below */ PORT_Memcpy(lastBlock, inbuf, inlen); PORT_Memset(lastBlock + inlen, 0, blocksize - inlen); rv = (*cts->cipher)(cts->context, outbuf, &tmp, maxout, lastBlock, blocksize, blocksize); PORT_Memset(lastBlock, 0, blocksize); if (rv == SECSuccess) { *outlen = written + blocksize; } else { PORT_Memset(saveout, 0, written + blocksize); } return rv; }
/* * create a new context which is the clone of the state of old context. */ PK11Context * PK11_CloneContext(PK11Context *old) { PK11Context *newcx; PRBool needFree = PR_FALSE; SECStatus rv = SECSuccess; void *data; unsigned long len; newcx = pk11_CreateNewContextInSlot(old->type, old->slot, old->operation, old->key, old->param); if (newcx == NULL) return NULL; /* now clone the save state. First we need to find the save state * of the old session. If the old context owns it's session, * the state needs to be saved, otherwise the state is in saveData. */ if (old->ownSession) { PK11_EnterContextMonitor(old); data = pk11_saveContext(old, NULL, &len); PK11_ExitContextMonitor(old); needFree = PR_TRUE; } else { data = old->savedData; len = old->savedLength; } if (data == NULL) { PK11_DestroyContext(newcx, PR_TRUE); return NULL; } /* now copy that state into our new context. Again we have different * work if the new context owns it's own session. If it does, we * restore the state gathered above. If it doesn't, we copy the * saveData pointer... */ if (newcx->ownSession) { PK11_EnterContextMonitor(newcx); rv = pk11_restoreContext(newcx, data, len); PK11_ExitContextMonitor(newcx); } else { PORT_Assert(newcx->savedData != NULL); if ((newcx->savedData == NULL) || (newcx->savedLength < len)) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); rv = SECFailure; } else { PORT_Memcpy(newcx->savedData, data, len); newcx->savedLength = len; } } if (needFree) PORT_Free(data); if (rv != SECSuccess) { PK11_DestroyContext(newcx, PR_TRUE); return NULL; } return newcx; }
SECStatus SECITEM_CopyItem(PLArenaPool *arena, SECItem *to, const SECItem *from) { to->type = from->type; if (from->data && from->len) { if ( arena ) { to->data = (unsigned char*) PORT_ArenaAlloc(arena, from->len); } else { to->data = (unsigned char*) PORT_Alloc(from->len); } if (!to->data) { return SECFailure; } PORT_Memcpy(to->data, from->data, from->len); to->len = from->len; } else { /* * If from->data is NULL but from->len is nonzero, this function * will succeed. Is this right? */ to->data = 0; to->len = 0; } return SECSuccess; }
/* * NOTE: This is not thread safe. Called at init time, and when loading * a new Entry. It is reasonably safe as long as it is not re-entered * (readers will always see a consistant table) * * This routine is called to add entries to the mechanism table, once there, * they can not be removed. */ void PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key, CK_MECHANISM_TYPE keyGen, CK_MECHANISM_TYPE padType, int ivLen, int blockSize) { int tableSize = pk11_MechTableSize; int size = pk11_MechEntrySize; int entry = size++; pk11MechanismData *old = pk11_MechanismTable; pk11MechanismData *newt = pk11_MechanismTable; if (size > tableSize) { int oldTableSize = tableSize; tableSize += 10; newt = PORT_NewArray(pk11MechanismData, tableSize); if (newt == NULL) return; if (old) PORT_Memcpy(newt, old, oldTableSize*sizeof(*newt)); } else old = NULL; newt[entry].type = type; newt[entry].keyType = key; newt[entry].keyGen = keyGen; newt[entry].padType = padType; newt[entry].iv = ivLen; newt[entry].blockSize = blockSize; pk11_MechanismTable = newt; pk11_MechTableSize = tableSize; pk11_MechEntrySize = size; if (old) PORT_Free(old); }
static SECStatus SetupAVAType(PRArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp) { unsigned char *oid; unsigned oidLen; unsigned char *cp; int maxLen; SECOidData *oidrec; oidrec = SECOID_FindOIDByTag(type); if (oidrec == NULL) return SECFailure; oid = oidrec->oid.data; oidLen = oidrec->oid.len; maxLen = cert_AVAOidTagToMaxLen(type); if (maxLen < 0) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen); if (cp == NULL) { return SECFailure; } it->len = oidLen; PORT_Memcpy(cp, oid, oidLen); *maxLenp = (unsigned)maxLen; return SECSuccess; }
/* * save the current context state into a variable. Required to make FORTEZZA * work. */ SECStatus PK11_SaveContext(PK11Context *cx,unsigned char *save,int *len, int saveLength) { unsigned char * data = NULL; CK_ULONG length = saveLength; if (cx->ownSession) { PK11_EnterContextMonitor(cx); data = pk11_saveContextHelper(cx, save, &length); PK11_ExitContextMonitor(cx); if (data) *len = length; } else if ((unsigned) saveLength >= cx->savedLength) { data = (unsigned char*)cx->savedData; if (cx->savedData) { PORT_Memcpy(save,cx->savedData,cx->savedLength); } *len = cx->savedLength; } if (data != NULL) { if (cx->ownSession) { PORT_ZFree(data, length); } return SECSuccess; } else { return SECFailure; } }
NS_IMETHODIMP nsNSSCertificateFakeTransport::Read(nsIObjectInputStream* aStream) { // This serialization has to match that of nsNSSCertificate, // so read the cachedEVStatus but don't actually use it. uint32_t cachedEVStatus; nsresult rv = aStream->Read32(&cachedEVStatus); if (NS_FAILED(rv)) { return rv; } uint32_t len; rv = aStream->Read32(&len); if (NS_FAILED(rv)) { return rv; } nsXPIDLCString str; rv = aStream->ReadBytes(len, getter_Copies(str)); if (NS_FAILED(rv)) { return rv; } // On a non-chrome process we cannot instatiate mCert because we lack // nsNSSComponent. nsNSSCertificateFakeTransport object is used only to // carry the certificate serialization. mCertSerialization = SECITEM_AllocItem(nullptr, nullptr, len); if (!mCertSerialization) return NS_ERROR_OUT_OF_MEMORY; PORT_Memcpy(mCertSerialization->data, str.Data(), len); return NS_OK; }
SECStatus CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher, const unsigned char *param, unsigned int blocksize) { const CK_AES_CTR_PARAMS *ctrParams = (const CK_AES_CTR_PARAMS *)param; if (ctrParams->ulCounterBits == 0 || ctrParams->ulCounterBits > blocksize * PR_BITS_PER_BYTE) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } /* Invariant: 0 < ctr->bufPtr <= blocksize */ ctr->bufPtr = blocksize; /* no unused data in the buffer */ ctr->cipher = cipher; ctr->context = context; ctr->counterBits = ctrParams->ulCounterBits; if (blocksize > sizeof(ctr->counter) || blocksize > sizeof(ctrParams->cb)) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize); return SECSuccess; }
/* same as above, but may allocate the return buffer. */ unsigned char * PK11_SaveContextAlloc(PK11Context *cx, unsigned char *preAllocBuf, unsigned int pabLen, unsigned int *stateLen) { unsigned char *stateBuf = NULL; unsigned long length = (unsigned long)pabLen; if (cx->ownSession) { PK11_EnterContextMonitor(cx); stateBuf = pk11_saveContextHelper(cx, preAllocBuf, &length); PK11_ExitContextMonitor(cx); *stateLen = (stateBuf != NULL) ? length : 0; } else { if (pabLen < cx->savedLength) { stateBuf = (unsigned char *)PORT_Alloc(cx->savedLength); if (!stateBuf) { return (unsigned char *)NULL; } } else { stateBuf = preAllocBuf; } if (cx->savedData) { PORT_Memcpy(stateBuf, cx->savedData, cx->savedLength); } *stateLen = cx->savedLength; } return stateBuf; }
/* * FUNCTION: PKIX_PL_ByteArray_GetPointer (see comments in pkix_pl_system.h) */ PKIX_Error * PKIX_PL_ByteArray_GetPointer( PKIX_PL_ByteArray *byteArray, void **pArray, void *plContext) { void *bytes = NULL; PKIX_ENTER(BYTEARRAY, "PKIX_PL_ByteArray_GetPointer"); PKIX_NULLCHECK_TWO(byteArray, pArray); if (byteArray->length != 0){ PKIX_CHECK(PKIX_PL_Malloc (byteArray->length, &bytes, plContext), PKIX_MALLOCFAILED); PKIX_BYTEARRAY_DEBUG("\tCalling PORT_Memcpy).\n"); (void) PORT_Memcpy (bytes, byteArray->array, byteArray->length); } *pArray = bytes; cleanup: if (PKIX_ERROR_RECEIVED){ PKIX_FREE(bytes); } PKIX_RETURN(BYTEARRAY); }
static char * mkCheckFileName(const char *libName) { int ln_len = PORT_Strlen(libName); char *output = PORT_Alloc(ln_len+sizeof(SGN_SUFFIX)); int index = ln_len + 1 - sizeof("."SHLIB_SUFFIX); if ((index > 0) && (PORT_Strncmp(&libName[index], "."SHLIB_SUFFIX,sizeof("."SHLIB_SUFFIX)) == 0)) { ln_len = index; } PORT_Memcpy(output,libName,ln_len); PORT_Memcpy(&output[ln_len],SGN_SUFFIX,sizeof(SGN_SUFFIX)); return output; }
static SECStatus AppendStr(stringBuf *bufp, char *str) { char *buf; unsigned bufLen, bufSize, len; int size = 0; /* Figure out how much to grow buf by (add in the '\0') */ buf = bufp->buffer; bufLen = bufp->offset; len = PORT_Strlen(str); bufSize = bufLen + len; if (!buf) { bufSize++; size = PR_MAX(DEFAULT_BUFFER_SIZE,bufSize*2); buf = (char *) PORT_Alloc(size); bufp->size = size; } else if (bufp->size < bufSize) { size = bufSize*2; buf =(char *) PORT_Realloc(buf,size); bufp->size = size; } if (!buf) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } bufp->buffer = buf; bufp->offset = bufSize; /* Concatenate str onto buf */ buf = buf + bufLen; if (bufLen) buf--; /* stomp on old '\0' */ PORT_Memcpy(buf, str, len+1); /* put in new null */ return SECSuccess; }
/* * Generates new random bytes and advances the internal prng state. * additional bytes are only used in algorithm testing. * * This function is specified in NIST SP 800-90 section 10.1.1.4 */ static SECStatus prng_generateNewBytes(RNGContext *rng, PRUint8 *returned_bytes, unsigned int no_of_returned_bytes, const PRUint8 *additional_input, unsigned int additional_input_len) { PRUint8 H[SHA256_LENGTH]; /* both H and w since they * aren't used concurrently */ unsigned int carry; int k1, k2; if (!rng->isValid) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } /* This code only triggers during tests, normal * prng operation does not use additional_input */ if (additional_input){ SHA256Context ctx; /* NIST SP 800-90 defines two temporaries in their calculations, * w and H. These temporaries are the same lengths, and used * at different times, so we use the following macro to collapse * them to the same variable, but keeping their unique names for * easy comparison to the spec */ #define w H rng->V_type = prngAdditionalDataType; SHA256_Begin(&ctx); SHA256_Update(&ctx, rng->V_Data, sizeof rng->V_Data); SHA256_Update(&ctx, additional_input, additional_input_len); SHA256_End(&ctx, w, NULL, sizeof w); PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w) PORT_Memset(w, 0, sizeof w); #undef w } if (no_of_returned_bytes == SHA256_LENGTH) { /* short_cut to hashbuf and save a copy and a clear */ SHA256_HashBuf(returned_bytes, V(rng), VSize(rng) ); } else { prng_Hashgen(rng, returned_bytes, no_of_returned_bytes); } /* advance our internal state... */ rng->V_type = prngGenerateByteType; SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data); PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof H) PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C); PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter, sizeof rng->reseed_counter) PRNG_ADD_CARRY_ONLY(rng->reseed_counter,(sizeof rng->reseed_counter)-1, 1); /* continuous rng check */ if (memcmp(V(rng), rng->oldV, sizeof rng->oldV) == 0) { rng->isValid = PR_FALSE; PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } PORT_Memcpy(rng->oldV, V(rng), sizeof rng->oldV); return SECSuccess; }
SHA1Context * SHA1_Resurrect(unsigned char *space,void *arg) { SHA1Context *cx = SHA1_NewContext(); if (cx == NULL) return NULL; PORT_Memcpy(cx,space, sizeof(SHA1Context)); return cx; }
/* * Update the global random number generator with more seeding * material. Use the Hash_DRBG reseed algorithm from NIST SP-800-90 * section 10.1.1.3 * * If entropy is NULL, it is fetched from the noise generator. */ static SECStatus prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len, const PRUint8 *additional_input, unsigned int additional_input_len) { PRUint8 noiseData[(sizeof rng->V_Data)+PRNG_SEEDLEN]; PRUint8 *noise = &noiseData[0]; /* if entropy wasn't supplied, fetch it. (normal operation case) */ if (entropy == NULL) { entropy_len = (unsigned int) RNG_SystemRNG( &noiseData[sizeof rng->V_Data], PRNG_SEEDLEN); } else { /* NOTE: this code is only available for testing, not to applications */ /* if entropy was too big for the stack variable, get it from malloc */ if (entropy_len > PRNG_SEEDLEN) { noise = PORT_Alloc(entropy_len + (sizeof rng->V_Data)); if (noise == NULL) { return SECFailure; } } PORT_Memcpy(&noise[sizeof rng->V_Data],entropy, entropy_len); } if (entropy_len < 256/PR_BITS_PER_BYTE) { /* noise == &noiseData[0] at this point, so nothing to free */ PORT_SetError(SEC_ERROR_NEED_RANDOM); return SECFailure; } rng->V_type = prngReseedType; PORT_Memcpy(noise, rng->V_Data, sizeof rng->V_Data); prng_Hash_df(V(rng), VSize(rng), noise, (sizeof rng->V_Data) + entropy_len, additional_input, additional_input_len); /* clear potential CSP */ PORT_Memset(noise, 0, (sizeof rng->V_Data) + entropy_len); rng->V_type = prngCGenerateType; prng_Hash_df(rng->C,sizeof rng->C,rng->V_Data,sizeof rng->V_Data,NULL,0); PRNG_RESET_RESEED_COUNT(rng) if (noise != &noiseData[0]) { PORT_Free(noise); } return SECSuccess; }
/* * check the consistancy and initialize a Private Key Object */ static CK_RV lg_createPrivateKeyObject(SDB *sdb, CK_KEY_TYPE key_type, CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count) { NSSLOWKEYPrivateKey *privKey; char *label; SECStatus rv = SECSuccess; CK_RV crv = CKR_DEVICE_ERROR; SECItem pubKey; NSSLOWKEYDBHandle *keyHandle = lg_getKeyDB(sdb); if (keyHandle == NULL) { return CKR_TOKEN_WRITE_PROTECTED; } privKey = lg_mkPrivKey(sdb, templ, count, key_type, &crv); if (privKey == NULL) return crv; label = lg_getString(CKA_LABEL, templ, count); crv = lg_Attribute2SSecItem(NULL, CKA_NETSCAPE_DB, templ, count, &pubKey); if (crv != CKR_OK) { crv = CKR_TEMPLATE_INCOMPLETE; rv = SECFailure; goto fail; } #ifdef notdef if (keyHandle->version != 3) { unsigned char buf[SHA1_LENGTH]; SHA1_HashBuf(buf, pubKey.data, pubKey.len); PORT_Memcpy(pubKey.data, buf, sizeof(buf)); pubKey.len = sizeof(buf); } #endif /* get the key type */ if (key_type == CKK_RSA) { rv = RSA_PrivateKeyCheck(&privKey->u.rsa); if (rv == SECFailure) { goto fail; } } rv = nsslowkey_StoreKeyByPublicKey(keyHandle, privKey, &pubKey, label, sdb /*->password*/); fail: if (label) PORT_Free(label); *handle = lg_mkHandle(sdb, &pubKey, LG_TOKEN_TYPE_PRIV); if (pubKey.data) PORT_Free(pubKey.data); lg_nsslowkey_DestroyPrivateKey(privKey); if (rv != SECSuccess) return crv; return CKR_OK; }
SECItem * _gca_datum_to_item_copy (PRArenaPool *arena, SECItem *item, const gnutls_datum_t *datum) { item->data = (unsigned char *)PORT_ArenaAlloc (arena, datum->size); if (!item->data) return NULL; item->len = datum->size; item->type = siBuffer; PORT_Memcpy (item->data, datum->data, datum->size); return item; }
static char * itemToString(SECItem *item) { char *string; string = PORT_ZAlloc(item->len+1); if (string == NULL) return NULL; PORT_Memcpy(string,item->data,item->len); string[item->len] = 0; return string; }
char * PORT_ArenaStrdup(PLArenaPool *arena, const char *str) { int len = PORT_Strlen(str)+1; char *newstr; newstr = (char*)PORT_ArenaAlloc(arena,len); if (newstr) { PORT_Memcpy(newstr,str,len); } return newstr; }
/* XXX depth and data_kind are unused; is there a PC way to silence warnings? */ static void sec_asn1e_encode_item_store (void *arg, const char *buf, unsigned long len, int depth, SEC_ASN1EncodingPart data_kind) { SECItem *dest; dest = (SECItem*)arg; PORT_Assert (dest != NULL); PORT_Memcpy (dest->data + dest->len, buf, len); dest->len += len; }
char * PORT_Strdup(const char *str) { size_t len = PORT_Strlen(str)+1; char *newstr; newstr = (char *)PORT_Alloc(len); if (newstr) { PORT_Memcpy(newstr, str, len); } return newstr; }