long int ast_more_random(void){ static aes_encrypt_ctx key; static int offset = 640; static int fd = -1; union { char plaintext[16]; long int ints[16 / sizeof(long int)]; } p = { .plaintext = "Asterisk rules!" }; static union { char enctext[640]; long int ints[640 / sizeof(long int)]; } e; long int res; ast_mutex_lock(&morerandomlock); /* Do we need to re-randomize? */ if (offset >= sizeof(e.enctext)) { int i; /* Obtain a new key */ if (fd < 0 && (fd = open("/dev/urandom", O_RDONLY)) < 0) { ast_log(LOG_ERROR, "Unable to open /dev/urandom. Random numbers will be a LOT less random.\n"); ast_mutex_unlock(&morerandomlock); return ast_random(); } read(fd, &key, sizeof(key)); for (i = 0; i < sizeof(e.enctext) - 15; i += 16) { /* Increment a counter in the plaintext block */ p.ints[16 / sizeof(long int) - 1]++; aes_encrypt(p.plaintext, &e.enctext[i], &key); } /* Reset pointer */ offset = 0; } res = e.ints[offset / sizeof(long int)]; offset += sizeof(long int); ast_mutex_unlock(&morerandomlock); return res;}