static bool CalculateMpqHashSha1(TMPQArchive * ha, PMPQ_SIGNATURE_INFO pSI, unsigned char * sha1_tail0, unsigned char * sha1_tail1, unsigned char * sha1_tail2) { ULONGLONG BeginBuffer; hash_state sha1_state_temp; hash_state sha1_state; LPBYTE pbDigestBuffer = NULL; // Allocate buffer for creating the MPQ digest. pbDigestBuffer = ALLOCMEM(BYTE, MPQ_DIGEST_UNIT_SIZE); if (pbDigestBuffer == NULL) return false; // Initialize SHA1 state structure sha1_init(&sha1_state); // Calculate begin of data to be hashed BeginBuffer = pSI->BeginMpqData; // Create the digest for (;;) { ULONGLONG BytesRemaining; DWORD dwToRead = MPQ_DIGEST_UNIT_SIZE; // Check the number of bytes remaining BytesRemaining = pSI->EndMpqData - BeginBuffer; if (BytesRemaining < MPQ_DIGEST_UNIT_SIZE) dwToRead = (DWORD)BytesRemaining; if (dwToRead == 0) break; // Read the next chunk if (!FileStream_Read(ha->pStream, &BeginBuffer, pbDigestBuffer, dwToRead)) { FREEMEM(pbDigestBuffer); return false; } // Pass the buffer to the hashing function sha1_process(&sha1_state, pbDigestBuffer, dwToRead); // Move pointers BeginBuffer += dwToRead; } // Add all three known tails and generate three hashes memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state)); sha1_done(&sha1_state_temp, sha1_tail0); memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state)); AddTailToSha1(&sha1_state_temp, GetPlainFileName(ha->pStream->szFileName)); sha1_done(&sha1_state_temp, sha1_tail1); memcpy(&sha1_state_temp, &sha1_state, sizeof(hash_state)); AddTailToSha1(&sha1_state_temp, "ARCHIVE"); sha1_done(&sha1_state_temp, sha1_tail2); // Finalize the MD5 hash FREEMEM(pbDigestBuffer); return true; }
/* return len bytes of pseudo-random data */ void genrandom(unsigned char* buf, unsigned int len) { hash_state hs; unsigned char hash[SHA1_HASH_SIZE]; unsigned int copylen; if (!donerandinit) { dropbear_exit("seedrandom not done"); } while (len > 0) { sha1_init(&hs); sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); sha1_process(&hs, (void*)&counter, sizeof(counter)); sha1_done(&hs, hash); counter++; if (counter > MAX_COUNTER) { seedrandom(); } copylen = MIN(len, SHA1_HASH_SIZE); memcpy(buf, hash, copylen); len -= copylen; buf += copylen; } m_burn(hash, sizeof(hash)); }
/** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int sha1_test(void) { static const struct { char* msg; unsigned char hash[20]; } tests[] = {{"abc", {0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d}}, {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1}}}; int i; unsigned char tmp[20]; sha1_state state; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { sha1_init(&state); sha1_process(&state, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); sha1_done(&state, tmp); if (memcpy(tmp, tests[i].hash, 20) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; }
int sha1_process_all(const unsigned char* in, unsigned long inlen, unsigned char* hash) { sha1_state state; sha1_init(&state); int err = sha1_process(&state, in, inlen); if (err != CRYPT_OK) { return err; } return sha1_done(&state, hash); }
void fuzz_seed(void) { hash_state hs; sha1_init(&hs); sha1_process(&hs, "fuzzfuzzfuzz", strlen("fuzzfuzzfuzz")); sha1_done(&hs, hashpool); counter = 0; donerandinit = 1; }
std::vector<unsigned char> sha1(const std::string &str) { std::vector<unsigned char> res(20, 0); hash_state hash; sha1_init(&hash); sha1_process(&hash, reinterpret_cast<const unsigned char*>(str.c_str()), str.length()); sha1_done(&hash, &*res.begin()); return res; }
/* Helper function for gen_new_keys, creates a hash. It makes a copy of the * already initialised hash_state hs, which should already have processed * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc. * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated. * The output will only be expanded once, since that is all that is required * (for 3DES and SHA, with 24 and 20 bytes respectively). * * See Section 5.2 of the IETF secsh Transport Draft for details */ static void hashkeys(unsigned char *out, int outlen, const hash_state * hs, const unsigned char X) { hash_state hs2; unsigned char k2[SHA1_HASH_SIZE]; /* used to extending */ memcpy(&hs2, hs, sizeof(hash_state)); sha1_process(&hs2, &X, 1); sha1_process(&hs2, ses.session_id, SHA1_HASH_SIZE); sha1_done(&hs2, out); if (SHA1_HASH_SIZE < outlen) { /* need to extend */ memcpy(&hs2, hs, sizeof(hash_state)); sha1_process(&hs2, out, SHA1_HASH_SIZE); sha1_done(&hs2, k2); memcpy(&out[SHA1_HASH_SIZE], k2, outlen - SHA1_HASH_SIZE); } }
static void delivery_callback ( cpg_handle_t handle, const struct cpg_name *groupName, uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len) { log_entry_t *log_pt; msg_t *msg_pt = (msg_t*)msg; msg_status_t status = MSG_OK; char status_buf[20]; unsigned char sha1_compare[20]; hash_state sha1_hash; if (record_messages_g == 0) { return; } msg_pt->seq = my_seq; my_seq++; if (nodeid != msg_pt->nodeid) { status = MSG_NODEID_ERR; } if (pid != msg_pt->pid) { status = MSG_PID_ERR; } if (msg_len != msg_pt->size) { status = MSG_SIZE_ERR; } sha1_init (&sha1_hash); sha1_process (&sha1_hash, msg_pt->payload, (msg_pt->size - sizeof (msg_t))); sha1_done (&sha1_hash, sha1_compare); if (memcmp (sha1_compare, msg_pt->sha1, 20) != 0) { syslog (LOG_ERR, "%s(); msg seq:%d; incorrect hash", __func__, msg_pt->seq); status = MSG_SHA1_ERR; } log_pt = malloc (sizeof(log_entry_t)); list_init (&log_pt->list); snprintf (log_pt->log, LOG_STR_SIZE, "%d:%d:%d:%s;", msg_pt->nodeid, msg_pt->pid, msg_pt->seq, err_status_string (status_buf, 20, status)); list_add_tail (&log_pt->list, &msg_log_head); total_stored_msgs++; // if ((total_stored_msgs % 100) == 0) { // syslog (LOG_INFO, "%s(); %d", __func__, total_stored_msgs); // } }
void addrandom(unsigned char * buf, unsigned int len) { hash_state hs; /* hash in the new seed data */ sha1_init(&hs); /* existing state (zeroes on startup) */ sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); /* new */ sha1_process(&hs, buf, len); sha1_done(&hs, hashpool); }
int sha1_buffer(const unsigned char *buffer, size_t len, unsigned char md[SHA_DIGEST_LENGTH]) { int rv=0; hash_state hs; EU_CHKN( rv = sha1_init( &hs)); EU_CHKN( rv = sha1_process( &hs, buffer, len)); EU_CHKN( rv = sha1_done( &hs, md)); out: return rv; }
/* * Computes a SHA-1 hash of 'input'. */ bool sha1(const unsigned char* input, const size_t inputLen, unsigned char* output) { hash_state hashState; if (sha1_init(&hashState) != CRYPT_OK) { return false; } if (sha1_process(&hashState, input, inputLen) != CRYPT_OK) { return false; } if (sha1_done(&hashState, output) != CRYPT_OK) { return false; } return true; }
void addrandom(const unsigned char * buf, unsigned int len) { hash_state hs; #if DROPBEAR_FUZZ if (fuzz.fuzzing) { return; } #endif /* hash in the new seed data */ sha1_init(&hs); /* existing state (zeroes on startup) */ sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); /* new */ sha1_process(&hs, buf, len); sha1_done(&hs, hashpool); }
/* hash the current random pool with some unique identifiers * for this process and point-in-time. this is used to separate * the random pools for fork()ed processes. */ void reseedrandom() { pid_t pid; hash_state hs; struct timeval tv; if (!donerandinit) { dropbear_exit("seedrandom not done"); } pid = getpid(); gettimeofday(&tv, NULL); sha1_init(&hs); sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); sha1_process(&hs, (void*)&pid, sizeof(pid)); sha1_process(&hs, (void*)&tv, sizeof(tv)); sha1_done(&hs, hashpool); }
static bool GetSha1ForFile( RageFileBasic &f, unsigned char *szHash ) { hash_state sha1e; sha1_init(&sha1e); int origpos = f.Tell(); f.Seek(0); unsigned char buf[4096]; int got = f.Read(buf, 4096); if ( got == -1 ) return false; while (got > 0) { sha1_process(&sha1e, buf, got); got = f.Read(buf, 4096); if ( got == -1 ) return false; } sha1_done(&sha1e, szHash); f.Seek(origpos); return true; }
/** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int sha1_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { const char *msg; unsigned char hash[20]; } tests[] = { { "abc", { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } } }; int i; unsigned char tmp[20]; hash_state md; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { sha1_init(&md); sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); sha1_done(&md, tmp); if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif }
/* initialise the prng from /dev/(u)random or prngd */ void seedrandom() { unsigned char readbuf[INIT_SEED_SIZE]; hash_state hs; /* initialise so that things won't warn about * hashing an undefined buffer */ if (!donerandinit) { m_burn(hashpool, sizeof(hashpool)); } /* get the seed data */ readrand(readbuf, sizeof(readbuf)); /* hash in the new seed data */ sha1_init(&hs); sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); sha1_process(&hs, (void*)readbuf, sizeof(readbuf)); sha1_done(&hs, hashpool); counter = 0; donerandinit = 1; }
/** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ INT sha1_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; UCHAR hash[20]; } tests[] = { { "abc", { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } } }; INT i; UCHAR tmp[20]; hash_state md; for (i = 0; i < (INT)(sizeof(tests) / sizeof(tests[0])); i++) { sha1_init(&md); sha1_process(&md, (UCHAR*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); sha1_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 20) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif }
/* Generate our side of the diffie-hellman key exchange value (dh_f), and * calculate the session key using the diffie-hellman algorithm. Following * that, the session hash is calculated, and signed with RSA or DSS. The * result is sent to the client. * * See the ietf-secsh-transport draft, section 6, for details */ static void send_msg_kexdh_reply(mp_int *dh_e) { mp_int dh_p, dh_q, dh_g, dh_y, dh_f; unsigned char randbuf[DH_P_LEN]; int dh_q_len; hash_state hs; TRACE(("enter send_msg_kexdh_reply")); assert(ses.kexstate.recvkexinit); m_mp_init_multi(&dh_g, &dh_p, &dh_q, &dh_y, &dh_f, NULL); /* read the prime and generator*/ if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN) != MP_OKAY) { dropbear_exit("Diffie-Hellman error"); } if (mp_set_int(&dh_g, dh_g_val) != MP_OKAY) { dropbear_exit("Diffie-Hellman error"); } /* calculate q = (p-1)/2 */ if (mp_sub_d(&dh_p, 1, &dh_y) != MP_OKAY) { /*dh_y is just a temp var here*/ dropbear_exit("Diffie-Hellman error"); } if (mp_div_2(&dh_y, &dh_q) != MP_OKAY) { dropbear_exit("Diffie-Hellman error"); } dh_q_len = mp_unsigned_bin_size(&dh_q); /* calculate our random value dh_y */ do { assert((unsigned int)dh_q_len <= sizeof(randbuf)); genrandom(randbuf, dh_q_len); if (mp_read_unsigned_bin(&dh_y, randbuf, dh_q_len) != MP_OKAY) { dropbear_exit("Diffie-Hellman error"); } } while (mp_cmp(&dh_y, &dh_q) == MP_GT || mp_cmp_d(&dh_y, 0) != MP_GT); /* f = g^y mod p */ if (mp_exptmod(&dh_g, &dh_y, &dh_p, &dh_f) != MP_OKAY) { dropbear_exit("Diffie-Hellman error"); } mp_clear(&dh_g); /* K = e^y mod p */ ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int)); m_mp_init(ses.dh_K); if (mp_exptmod(dh_e, &dh_y, &dh_p, ses.dh_K) != MP_OKAY) { dropbear_exit("Diffie-Hellman error"); } /* clear no longer needed vars */ mp_clear_multi(&dh_y, &dh_p, &dh_q, NULL); /* Create the remainder of the hash buffer, to generate the exchange hash */ /* K_S, the host key */ buf_put_pub_key(ses.kexhashbuf, ses.opts->hostkey, ses.newkeys->algo_hostkey); /* e, exchange value sent by the client */ buf_putmpint(ses.kexhashbuf, dh_e); /* f, exchange value sent by the server */ buf_putmpint(ses.kexhashbuf, &dh_f); /* K, the shared secret */ buf_putmpint(ses.kexhashbuf, ses.dh_K); /* calculate the hash H to sign */ sha1_init(&hs); buf_setpos(ses.kexhashbuf, 0); sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len), ses.kexhashbuf->len); sha1_done(&hs, ses.hash); buf_free(ses.kexhashbuf); ses.kexhashbuf = NULL; /* first time around, we set the session_id to H */ if (ses.session_id == NULL) { /* create the session_id, this never needs freeing */ ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE); memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE); } /* we can start creating the kexdh_reply packet */ CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_REPLY); buf_put_pub_key(ses.writepayload, ses.opts->hostkey, ses.newkeys->algo_hostkey); /* put f */ buf_putmpint(ses.writepayload, &dh_f); mp_clear(&dh_f); /* calc the signature */ buf_put_sign(ses.writepayload, ses.opts->hostkey, ses.newkeys->algo_hostkey, ses.hash, SHA1_HASH_SIZE); /* the SSH_MSG_KEXDH_REPLY is done */ encrypt_packet(); TRACE(("leave send_msg_kexdh_reply")); }
static void send_some_more_messages_zcb (void) { msg_t *my_msg; int i; int send_now; size_t payload_size; size_t total_size; hash_state sha1_hash; cs_error_t res; cpg_flow_control_state_t fc_state; void *zcb_buffer; if (cpg_fd < 0) return; send_now = my_msgs_to_send; payload_size = (rand() % 100000); total_size = payload_size + sizeof (msg_t); cpg_zcb_alloc (cpg_handle, total_size, &zcb_buffer); my_msg = (msg_t*)zcb_buffer; //syslog (LOG_DEBUG,"%s() send_now:%d", __func__, send_now); my_msg->pid = my_pid; my_msg->nodeid = my_nodeid; my_msg->size = sizeof (msg_t) + payload_size; my_msg->seq = 0; for (i = 0; i < payload_size; i++) { my_msg->payload[i] = i; } sha1_init (&sha1_hash); sha1_process (&sha1_hash, my_msg->payload, payload_size); sha1_done (&sha1_hash, my_msg->sha1); for (i = 0; i < send_now; i++) { res = cpg_flow_control_state_get (cpg_handle, &fc_state); if (res == CS_OK && fc_state == CPG_FLOW_CONTROL_ENABLED) { /* lets do this later */ send_some_more_messages_later (); syslog (LOG_INFO, "%s() flow control enabled.", __func__); goto free_buffer; } res = cpg_zcb_mcast_joined (cpg_handle, CPG_TYPE_AGREED, zcb_buffer, total_size); if (res == CS_ERR_TRY_AGAIN) { /* lets do this later */ send_some_more_messages_later (); // if (i > 0) { // syslog (LOG_INFO, "%s() TRY_AGAIN %d to send.", // __func__, my_msgs_to_send); // } goto free_buffer; } else if (res != CS_OK) { syslog (LOG_ERR, "%s() -> cpg_mcast_joined error:%d, exiting.", __func__, res); exit (-2); } my_msgs_to_send--; } free_buffer: cpg_zcb_free (cpg_handle, zcb_buffer); }
static void send_some_more_messages_normal (void) { msg_t my_msg; struct iovec iov[2]; int i; int send_now; size_t payload_size; hash_state sha1_hash; cs_error_t res; cpg_flow_control_state_t fc_state; int retries = 0; time_t before; if (cpg_fd < 0) return; send_now = my_msgs_to_send; //syslog (LOG_DEBUG,"%s() send_now:%d", __func__, send_now); my_msg.pid = my_pid; my_msg.nodeid = my_nodeid; payload_size = (rand() % 100000); my_msg.size = sizeof (msg_t) + payload_size; my_msg.seq = 0; for (i = 0; i < payload_size; i++) { buffer[i] = i; } sha1_init (&sha1_hash); sha1_process (&sha1_hash, buffer, payload_size); sha1_done (&sha1_hash, my_msg.sha1); iov[0].iov_len = sizeof (msg_t); iov[0].iov_base = &my_msg; iov[1].iov_len = payload_size; iov[1].iov_base = buffer; for (i = 0; i < send_now; i++) { if (in_cnchg && pcmk_test) { retries = 0; before = time(NULL); cs_repeat(retries, 30, res = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2)); if (retries > 20) { syslog (LOG_ERR, "%s() -> cs_repeat: blocked for :%lu secs.", __func__, (unsigned long)(time(NULL) - before)); } if (res != CS_OK) { syslog (LOG_ERR, "%s() -> cpg_mcast_joined error:%d.", __func__, res); return; } } else { res = cpg_flow_control_state_get (cpg_handle, &fc_state); if (res == CS_OK && fc_state == CPG_FLOW_CONTROL_ENABLED) { /* lets do this later */ send_some_more_messages_later (); syslog (LOG_INFO, "%s() flow control enabled.", __func__); return; } res = cpg_mcast_joined (cpg_handle, CPG_TYPE_AGREED, iov, 2); if (res == CS_ERR_TRY_AGAIN) { /* lets do this later */ send_some_more_messages_later (); if (i > 0) { syslog (LOG_INFO, "%s() TRY_AGAIN %d to send.", __func__, my_msgs_to_send); } return; } else if (res != CS_OK) { syslog (LOG_ERR, "%s() -> cpg_mcast_joined error:%d, exiting.", __func__, res); exit (-2); } } my_msgs_to_send--; } }
/** * End of copied SHA1 code. * * ------------------------------------------------------------------------ */ void getDigest_1(void *digest,void *input,int len){ struct sha1_state mystate; sha1_init(&mystate); sha1_process(&mystate,input,len); sha1_done(&mystate,digest); }
/* Initialise the prng from /dev/urandom or prngd. This function can * be called multiple times */ void seedrandom() { hash_state hs; pid_t pid; struct timeval tv; clock_t clockval; /* hash in the new seed data */ sha1_init(&hs); /* existing state */ sha1_process(&hs, (void*)hashpool, sizeof(hashpool)); #ifdef DROPBEAR_PRNGD_SOCKET if (process_file(&hs, DROPBEAR_PRNGD_SOCKET, INIT_SEED_SIZE, 1) != DROPBEAR_SUCCESS) { dropbear_exit("Failure reading random device %s", DROPBEAR_PRNGD_SOCKET); } #else /* non-blocking random source (probably /dev/urandom) */ if (process_file(&hs, DROPBEAR_URANDOM_DEV, INIT_SEED_SIZE, 0) != DROPBEAR_SUCCESS) { dropbear_exit("Failure reading random device %s", DROPBEAR_URANDOM_DEV); } #endif /* A few other sources to fall back on. * Add more here for other platforms */ #ifdef __linux__ /* Seems to be a reasonable source of entropy from timers. Possibly hard * for even local attackers to reproduce */ process_file(&hs, "/proc/timer_list", 0, 0); /* Might help on systems with wireless */ process_file(&hs, "/proc/interrupts", 0, 0); process_file(&hs, "/proc/loadavg", 0, 0); process_file(&hs, "/proc/sys/kernel/random/entropy_avail", 0, 0); /* Mostly network visible but useful in some situations. * Limit size to avoid slowdowns on systems with lots of routes */ process_file(&hs, "/proc/net/netstat", 4096, 0); process_file(&hs, "/proc/net/dev", 4096, 0); process_file(&hs, "/proc/net/tcp", 4096, 0); /* Also includes interface lo */ process_file(&hs, "/proc/net/rt_cache", 4096, 0); process_file(&hs, "/proc/vmstat", 0, 0); #endif pid = getpid(); sha1_process(&hs, (void*)&pid, sizeof(pid)); /* gettimeofday() doesn't completely fill out struct timeval on OS X (10.8.3), avoid valgrind warnings by clearing it first */ memset(&tv, 0x0, sizeof(tv)); gettimeofday(&tv, NULL); sha1_process(&hs, (void*)&tv, sizeof(tv)); clockval = clock(); sha1_process(&hs, (void*)&clockval, sizeof(clockval)); /* When a private key is read by the client or server it will * be added to the hashpool - see runopts.c */ sha1_done(&hs, hashpool); counter = 0; donerandinit = 1; /* Feed it all back into /dev/urandom - this might help if Dropbear * is running from inetd and gets new state each time */ write_urandom(); }
void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt) { byte AESKey[16],AESInit[16]; bool Cached=false; for (uint I=0;I<ASIZE(KDF3Cache);I++) if (KDF3Cache[I].Pwd==*Password && (Salt==NULL && !KDF3Cache[I].SaltPresent || Salt!=NULL && KDF3Cache[I].SaltPresent && memcmp(KDF3Cache[I].Salt,Salt,SIZE_SALT30)==0)) { memcpy(AESKey,KDF3Cache[I].Key,sizeof(AESKey)); memcpy(AESInit,KDF3Cache[I].Init,sizeof(AESInit)); Cached=true; break; } if (!Cached) { byte RawPsw[2*MAXPASSWORD+SIZE_SALT30]; WideToRaw(PwdW,RawPsw,ASIZE(RawPsw)); size_t RawLength=2*wcslen(PwdW); if (Salt!=NULL) { memcpy(RawPsw+RawLength,Salt,SIZE_SALT30); RawLength+=SIZE_SALT30; } sha1_context c; sha1_init(&c); const int HashRounds=0x40000; for (int I=0;I<HashRounds;I++) { sha1_process( &c, RawPsw, RawLength, false); byte PswNum[3]; PswNum[0]=(byte)I; PswNum[1]=(byte)(I>>8); PswNum[2]=(byte)(I>>16); sha1_process( &c, PswNum, 3, false); if (I%(HashRounds/16)==0) { sha1_context tempc=c; uint32 digest[5]; sha1_done( &tempc, digest, false); AESInit[I/(HashRounds/16)]=(byte)digest[4]; } } uint32 digest[5]; sha1_done( &c, digest, false); for (int I=0;I<4;I++) for (int J=0;J<4;J++) AESKey[I*4+J]=(byte)(digest[I]>>(J*8)); KDF3Cache[KDF3CachePos].Pwd=*Password; if ((KDF3Cache[KDF3CachePos].SaltPresent=(Salt!=NULL))==true) memcpy(KDF3Cache[KDF3CachePos].Salt,Salt,SIZE_SALT30); memcpy(KDF3Cache[KDF3CachePos].Key,AESKey,sizeof(AESKey)); memcpy(KDF3Cache[KDF3CachePos].Init,AESInit,sizeof(AESInit)); KDF3CachePos=(KDF3CachePos+1)%ASIZE(KDF3Cache); cleandata(RawPsw,sizeof(RawPsw)); }