/* os_get_random - Get cryptographically strong pseudo random data : * Buffer for pseudo random data : * Length of the buffer Returns: * 0 on success, -1 on failure */ int ICACHE_FLASH_ATTR os_get_random(unsigned char * buf, size_t len) { if(buf != NULL) { while(len) { uint32 z = phy_get_rand(); do { *buf++ = (char)z; z >>= 8; } while(--len & 3); } } return 0; }
/** * Set a series of bytes with a random number. Individual bytes can be 0 */ EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data) { #if !defined(WIN32) && defined(CONFIG_USE_DEV_URANDOM) /* use the Linux default */ read(rng_fd, rand_data, num_rand_bytes); /* read from /dev/urandom */ #elif defined(WIN32) && defined(CONFIG_WIN32_USE_CRYPTO_LIB) /* use Microsoft Crypto Libraries */ CryptGenRandom(gCryptProv, num_rand_bytes, rand_data); #elif defined(ESP8266) for (size_t cb = 0; cb < num_rand_bytes; cb += 4) { uint32_t r = phy_get_rand(); size_t left = num_rand_bytes - cb; left = (left < 4) ? left : 4; memcpy(rand_data + cb, &r, left); } #else /* nothing else to use, so use a custom RNG */ /* The method we use when we've got nothing better. Use RC4, time and a couple of random seeds to generate a random sequence */ RC4_CTX rng_ctx; struct timeval tv; MD5_CTX rng_digest_ctx; uint8_t digest[MD5_SIZE]; uint64_t *ep; int i; /* A proper implementation would use counters etc for entropy */ gettimeofday(&tv, NULL); ep = (uint64_t *)entropy_pool; ep[0] ^= ENTROPY_COUNTER1; ep[1] ^= ENTROPY_COUNTER2; /* use a digested version of the entropy pool as a key */ MD5_Init(&rng_digest_ctx); MD5_Update(&rng_digest_ctx, entropy_pool, ENTROPY_POOL_SIZE); MD5_Final(digest, &rng_digest_ctx); /* come up with the random sequence */ RC4_setup(&rng_ctx, digest, MD5_SIZE); /* use as a key */ memcpy(rand_data, entropy_pool, num_rand_bytes < ENTROPY_POOL_SIZE ? num_rand_bytes : ENTROPY_POOL_SIZE); RC4_crypt(&rng_ctx, rand_data, rand_data, num_rand_bytes); /* move things along */ for (i = ENTROPY_POOL_SIZE-1; i >= MD5_SIZE ; i--) entropy_pool[i] = entropy_pool[i-MD5_SIZE]; /* insert the digest at the start of the entropy pool */ memcpy(entropy_pool, digest, MD5_SIZE); #endif }
// Restores settings to default. Prevents accidental calling //usage: First call with no parameter, then call with returned code // resetSystemSettings(resetSystemSettings()); uint32_t resetSystemSettings(uint32_t code/* = 0*/) { static uint32_t challenge=0; const char* naStr = "na"; if(code == 0) { challenge = phy_get_rand(); } else if(code == challenge) { if(FIRMWARE_VER_MAJOR == 1) { if(FIRMWARE_VER_MINOR == 0) /* for 01.00 */ { gSysCfg.fwVerMinor = FIRMWARE_VER_MINOR; gSysCfg.fwVerMajor = FIRMWARE_VER_MAJOR; gSysCfg.wifiStationIsConfigured = 0; if(gSysCfg.wifiSSID) free(gSysCfg.wifiSSID); gSysCfg.wifiSSID = new char[sizeof(naStr)+1]; memcpy(gSysCfg.wifiSSID, naStr, sizeof(naStr)+1); if(gSysCfg.wifiPwd) free(gSysCfg.wifiPwd); gSysCfg.wifiPwd = new char[sizeof(naStr)+1]; memcpy(gSysCfg.wifiPwd, naStr, sizeof(naStr)+1); gSysCfg.dbgNumRestarts = 0; gSysCfg.lastKnownTimeStamp = 0; gSysCfg.timeZone = 2; } } } return challenge; }
uint32 ICACHE_FLASH_ATTR os_random(void) { return phy_get_rand(); }