/* * Generate a random bignum of a specified length, with the given * high and low 8 bits. "High" is merged into the high 8 bits of the * number. For example, set it to 0x80 to ensure that the number is * exactly "bits" bits long (i.e. 2^(bits-1) <= bn < 2^bits). * "Low" is merged into the low 8 bits. For example, set it to * 1 to ensure that you generate an odd number. */ static int genRandBn(struct BigNum *bn, unsigned bits, byte high, byte low) { unsigned char buf[64]; unsigned bytes; unsigned l; int err; bnSetQ(bn, 0); bytes = (bits+7) / 8; l = bytes < sizeof(buf) ? bytes : sizeof(buf); randBytes(buf, l); /* Mask off excess high bits */ buf[0] &= 255 >> (-bits & 7); /* Merge in specified high bits */ buf[0] |= high >> (-bits & 7); if (bits & 7) buf[1] |= high << (bits & 7); for (;;) { bytes -= l; if (!bytes) /* Last word - merge in low bits */ buf[l-1] |= low; err = bnInsertBigBytes(bn, buf, bytes, l); if (!bytes || err < 0) break; l = bytes < sizeof(buf) ? bytes : sizeof(buf); randBytes(buf, l); } memset(buf, 0, sizeof(buf)); return err; }
size_t rand_pool_acquire_entropy(RAND_POOL *pool) { # if defined(RAND_SEED_VXRANDLIB) /* vxRandLib based entropy method */ size_t bytes_needed; bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); if (bytes_needed > 0) { int retryCount = 0; STATUS result = ERROR; unsigned char *buffer; buffer = rand_pool_add_begin(pool, bytes_needed); while ((result != OK) && (retryCount < 10)) { RANDOM_NUM_GEN_STATUS status = randStatus(); if ((status == RANDOM_NUM_GEN_ENOUGH_ENTROPY) || (status == RANDOM_NUM_GEN_MAX_ENTROPY) ) { result = randBytes(buffer, bytes_needed); if (result == OK) rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); /* * no else here: randStatus said ok, if randBytes failed * it will result in another loop or no entropy */ } else { /* * give a minimum delay here to allow OS to collect more * entropy. taskDelay duration will depend on the system tick, * this is by design as the sw-random lib uses interrupts * which will at least happen during ticks */ taskDelay(5); } retryCount++; } } return rand_pool_entropy_available(pool); # else /* * SEED_NONE means none, without randlib we dont have entropy and * rely on it being added externally */ return rand_pool_entropy_available(pool); # endif /* defined(RAND_SEED_VXRANDLIB) */ }
int main(int argc, char **argv) { unsigned char buf[NBYTES]; unsigned poker[16]; unsigned onebits; unsigned runzero[MAXRUNSTAT], runone[MAXRUNSTAT]; unsigned maxrun; unsigned long t; unsigned i; int passed; int numfailed = 0; char *p; if (argc != 2) { fprintf(stderr, "Usage: %s <bits>\n" "Accumulate random bits and then do randomness tests on the RNG output.\n", argv[0]); return 1; } t = strtoul(argv[1], &p, 0); if (t > 3072 || *p) { fprintf(stderr, "Illegal number of bits: \"%s\"\n", argv[1]); return 1; } randAccum(t); randBytes(buf, sizeof(buf)); onebits = pokerstat(buf, poker); passed = (9654 < onebits) && (onebits < 10346); numfailed += !passed; printf("\nNumber of one bits: 9654 < %u < 10346: %s\n", onebits, passed ? "Pass " : "FAIL *"); /* * Original test asks for * X = (16/5000) * sum(poker[i]^2, i = 0..15) - 5000, * and requires that 1.03 < X < 57.4. * This test uses t = 5000/16 * X, and requires that * 321.875 < t < 17937.5. Note that if the distribution * were totally flat, t would be 0, which is *also* bad. */ t = 0; for (i = 0; i < 16; i++) { printf("poker[%u%u%u%u] =%4u %c", i>>3, i>>2 & 1, i>>1 & 1, i & 1, poker[i],(~i & 3) ? ' ' : '\n'); t += (unsigned long)poker[i] * poker[i]; } t -= 5000ul * 5000 / 16; passed = (321 < t) && (t < 17938); numfailed += !passed; printf("Poker parameter: 321.875 < %lu < 17937.5: %s\n", t, passed ? "Pass " : "FAIL *"); /* * Next, we're asked to count runs of consecutive ones and * zeroes. The shortest possible run is of length 1. * The longest, 20000. Since the byte ordering is not defined, * do it both ways! This tallies the run lengths of all * zeros and all ones, giving totals for the short runs * and the longest run of either size encountered. */ printf("\nBig-endian run tests:\n"); maxrun = countrunsbig(buf, runzero, runone); numfailed += checkruns(runzero, runone, maxrun); printf("\nLittle-endian run tests:\n"); maxrun = countrunslittle(buf, runzero, runone); numfailed += checkruns(runzero, runone, maxrun); /* * Tests are: * 1 - Number of one bits * 1 - Poker test * 12 - Big-endian run length tests * 1 - Big-endian maximum run length test * 12 - Little-endian run length tests * 1 - Little-endian maximum run length test */ printf("\nOut of 28 tests, %d tests failed.\n", numfailed); return numfailed; }
bool SASLAuthFeature::xmppStanzaIn(IXmppStream *AXmppStream, Stanza &AStanza, int AOrder) { if (AXmppStream==FXmppStream && AOrder==XSHO_XMPP_FEATURE) { if (AStanza.kind() == "challenge") { QByteArray challengeData = QByteArray::fromBase64(AStanza.element().text().toLatin1()); LOG_STRM_DEBUG(FXmppStream->streamJid(),QString("SASL auth challenge received: %1").arg(QString::fromUtf8(challengeData))); QMap<QByteArray, QByteArray> responseMap; QMap<QByteArray, QByteArray> challengeMap = parseChallenge(challengeData); if (challengeMap.value("qop") == "auth") { QByteArray randBytes(32,' '); for (int i=0; i<randBytes.size(); i++) randBytes[i] = (char) (256.0 * qrand() / (RAND_MAX + 1.0)); responseMap["cnonce"] = randBytes.toHex(); if (challengeMap.contains("realm")) responseMap["realm"] = challengeMap.value("realm"); else responseMap["realm"] = FXmppStream->streamJid().pDomain().toUtf8(); responseMap["username"] = FXmppStream->streamJid().pNode().toUtf8(); responseMap["nonce"] = challengeMap.value("nonce"); responseMap["nc"] = "00000001"; responseMap["qop"] = "auth"; responseMap["digest-uri"] = QString("xmpp/%1").arg(FXmppStream->streamJid().pDomain()).toUtf8(); responseMap["charset"] = "utf-8"; responseMap["response"] = getResponseValue(responseMap,FXmppStream->password()); } QByteArray responseData = serializeResponse(responseMap); Stanza response("response",NS_FEATURE_SASL); response.element().appendChild(response.createTextNode(responseData.toBase64())); FXmppStream->sendStanza(response); LOG_STRM_DEBUG(FXmppStream->streamJid(),QString("SASL auth response sent: %1").arg(QString::fromUtf8(responseData))); } else { FXmppStream->removeXmppStanzaHandler(XSHO_XMPP_FEATURE,this); if (AStanza.kind() == "success") { LOG_STRM_INFO(FXmppStream->streamJid(),"Authorization successes"); deleteLater(); emit finished(true); } else if (AStanza.kind() == "failure") { XmppSaslError err(AStanza.element()); LOG_STRM_WARNING(FXmppStream->streamJid(),QString("Authorization failed: %1").arg(err.condition())); emit error(err); } else { XmppError err(IERR_SASL_AUTH_INVALID_RESPONSE); LOG_STRM_WARNING(FXmppStream->streamJid(),QString("Authorization error: Invalid stanza kind=%1").arg(AStanza.kind())); emit error(err); } } return true; } return false; }