/* Compute the sha1 of string at 's' with 'len' bytes long. * The SHA1 is then xored against the string pointed by digest. * Since xor is commutative, this operation is used in order to * "add" digests relative to unordered elements. * * So digest(a,b,c,d) will be the same of digest(b,a,c,d) */ void xorDigest(unsigned char *digest, void *ptr, size_t len) { SHA1_CTX ctx; unsigned char hash[20], *s = ptr; int j; SHA1Init(&ctx); SHA1Update(&ctx,s,len); SHA1Final(hash,&ctx); for (j = 0; j < 20; j++) digest[j] ^= hash[j]; }
static int keycrunch_sha1(char *result, char *seed, char *passwd) { char *buf; SHA1_CTX sha; unsigned int buflen; int i, j; /* * If seed and passwd are defined we are in keycrunch() mode, * else we are in f() mode. */ if (seed && passwd) { buflen = strlen(seed) + strlen(passwd); if ((buf = malloc(buflen + 1)) == NULL) return(-1); (void)strlcpy(buf, seed, buflen + 1); lowcase(buf); (void)strlcat(buf, passwd, buflen + 1); sevenbit(buf); } else { buf = result; buflen = SKEY_BINKEY_SIZE; } /* Crunch the key through SHA1 */ SHA1Init(&sha); SHA1Update(&sha, (unsigned char *)buf, buflen); SHA1Pad(&sha); /* Fold 160 to 64 bits */ sha.state[0] ^= sha.state[2]; sha.state[1] ^= sha.state[3]; sha.state[0] ^= sha.state[4]; /* * SHA1 is a big endian algorithm but RFC2289 mandates that * the result be in little endian form, so we copy to the * result buffer manually. */ for (i = 0, j = 0; j < 8; i++, j += 4) { result[j] = (u_char)(sha.state[i] & 0xff); result[j+1] = (u_char)((sha.state[i] >> 8) & 0xff); result[j+2] = (u_char)((sha.state[i] >> 16) & 0xff); result[j+3] = (u_char)((sha.state[i] >> 24) & 0xff); } if (buf != result) (void)free(buf); return(0); }
int SHA1Hash::Process(const void * _data, size_t _length) { CoreAssert(this != NULL); Reset(); if (!_length || !_data) return -1; SHA1Update(&m_state, (unsigned char *)_data, (unsigned int)_length); m_hash = new unsigned char[SHA1_DIGEST_SIZE]; SHA1Final(m_hash, &m_state); return 0; }
IoObject *IoSHA1_appendSeq(IoSHA1 *self, IoObject *locals, IoMessage *m) { /*doc SHA1 appendSeq(aSequence) Appends aSequence to the hash calculation. Returns self. */ IoSeq *buffer = IoMessage_locals_seqArgAt_(m, locals, 0); IOASSERT(DATA(self)->isDone == 0, "cannot append to an already calculated sha1"); SHA1Update(&(DATA(self)->context), (unsigned char const *)IoSeq_rawBytes(buffer), IoSeq_rawSize(buffer)); return self; }
void mhash_sha1_buf(unsigned char *in, size_t len, unsigned char out[20]) { SHA1_CTX contex; unsigned int ii; memset(out, 0x0, 20); SHA1Init(&contex); for (ii = 0; ii < len; ii++) { SHA1Update(&contex, in + ii, 1); } SHA1Final(out, &contex); }
app_action_t application_function_flash_checksum(string_t *src, string_t *dst) { unsigned int address, current, length, done; SHA_CTX sha_context; unsigned char sha_result[SHA_DIGEST_LENGTH]; string_new(, sha_string, SHA_DIGEST_LENGTH * 2 + 2); if(parse_uint(1, src, &address, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-checksum: address required\n"); return(app_action_error); } if(parse_uint(2, src, &length, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-checksum: length required\n"); return(app_action_error); } if((address % SPI_FLASH_SEC_SIZE) != 0) { string_append(dst, "ERROR: flash_checksum: address should be divisible by flash sector size"); return(app_action_error); } if((length % SPI_FLASH_SEC_SIZE) != 0) { string_append(dst, "ERROR: flash_checksum: length should be divisible by flash sector size"); return(app_action_error); } SHA1Init(&sha_context); for(current = address, done = 0; done < length; current += SPI_FLASH_SEC_SIZE, done += SPI_FLASH_SEC_SIZE) { spi_flash_read(current, string_buffer_nonconst(dst), SPI_FLASH_SEC_SIZE); SHA1Update(&sha_context, string_buffer(dst), SPI_FLASH_SEC_SIZE); } SHA1Final(sha_result, &sha_context); string_bin_to_hex(&sha_string, sha_result, SHA_DIGEST_LENGTH); string_clear(dst); string_format(dst, "OK flash-checksum: checksummed bytes: %u, from address: %u, checksum: ", done, address); string_append_string(dst, &sha_string); string_append(dst, "\n"); return(app_action_normal); }
char *cs_calcchallenge(const unsigned char *entropy) { unsigned char buf[20]; static char hexbuf[sizeof(buf) * 2 + 1]; SHA1_CTX ctx; SHA1Init(&ctx); /* we can maybe add a salt here in the future */ SHA1Update(&ctx, entropy, ENTROPYLEN); SHA1Final(buf, &ctx); hmac_printhex(buf, hexbuf, 16); return hexbuf; }
static inline void tnt_scramble_prepare(void *out, const void *salt, const void *pass, int plen) { unsigned char hash1[TNT_SCRAMBLE_SIZE]; unsigned char hash2[TNT_SCRAMBLE_SIZE]; SHA1_CTX ctx; SHA1Init(&ctx); SHA1Update(&ctx, (const unsigned char *) pass, plen); SHA1Final(hash1, &ctx); SHA1Init(&ctx); SHA1Update(&ctx, hash1, TNT_SCRAMBLE_SIZE); SHA1Final(hash2, &ctx); SHA1Init(&ctx); SHA1Update(&ctx, (const unsigned char *) salt, TNT_SCRAMBLE_SIZE); SHA1Update(&ctx, hash2, TNT_SCRAMBLE_SIZE); SHA1Final((unsigned char *) out, &ctx); tnt_xor((unsigned char *) out, hash1, (const unsigned char *) out, TNT_SCRAMBLE_SIZE); }
static void ikev2_calculate_sighash(struct state *st, enum phase1_role role, unsigned char *idhash, chunk_t firstpacket, unsigned char *sig_octets) { SHA1_CTX ctx_sha1; const chunk_t *nonce; const char *nonce_name; if (role == INITIATOR) { /* on initiator, we need to hash responders nonce */ nonce = &st->st_nr; nonce_name = "inputs to hash2 (responder nonce)"; } else { nonce = &st->st_ni; nonce_name = "inputs to hash2 (initiator nonce)"; } DBG(DBG_CRYPT, DBG_dump_chunk("inputs to hash1 (first packet)", firstpacket); DBG_dump_chunk(nonce_name, *nonce); DBG_dump("idhash", idhash, st->st_oakley.prf_hasher->hash_digest_len)); SHA1Init(&ctx_sha1); SHA1Update(&ctx_sha1, firstpacket.ptr, firstpacket.len); SHA1Update(&ctx_sha1, nonce->ptr, nonce->len); /* we took the PRF(SK_d,ID[ir]'), so length is prf hash length */ SHA1Update(&ctx_sha1, idhash, st->st_oakley.prf_hasher->hash_digest_len); SHA1Final(sig_octets, &ctx_sha1); }
bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) { switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Doesn't return anything ... */ MD5_Update(&digest->md5, (unsigned char *) data, length); return true; case CRYPTO_DIGEST_SHA1: /* Doesn't return anything ... */ SHA1Update(&digest->sha1, (const u_int8_t *) data, (unsigned int)length); return true; default: return false; } }
app_action_t application_function_flash_read(string_t *src, string_t *dst) { unsigned int address, sector; SHA_CTX sha_context; unsigned char sha_result[SHA_DIGEST_LENGTH]; string_new(, sha_string, SHA_DIGEST_LENGTH * 2 + 2); if(string_size(&flash_sector_buffer) < SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-read: flash sector buffer too small: %d\n", string_size(&flash_sector_buffer)); return(app_action_error); } if(parse_uint(1, src, &address, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-read: address required\n"); return(app_action_error); } if((address % SPI_FLASH_SEC_SIZE) != 0) { string_append(dst, "ERROR flash-read: address should be divisible by flash sector size"); return(app_action_error); } if((flash_sector_buffer_use != fsb_free) && (flash_sector_buffer_use != fsb_config_cache)) { string_format(dst, "ERROR: flash-read: sector buffer in use: %u\n", flash_sector_buffer_use); return(app_action_error); } flash_sector_buffer_use = fsb_ota; sector = address / SPI_FLASH_SEC_SIZE; spi_flash_read(sector * SPI_FLASH_SEC_SIZE, string_buffer_nonconst(&flash_sector_buffer), SPI_FLASH_SEC_SIZE); string_setlength(&flash_sector_buffer, SPI_FLASH_SEC_SIZE); SHA1Init(&sha_context); SHA1Update(&sha_context, string_buffer(&flash_sector_buffer), SPI_FLASH_SEC_SIZE); SHA1Final(sha_result, &sha_context); string_bin_to_hex(&sha_string, sha_result, SHA_DIGEST_LENGTH); string_format(dst, "OK flash-read: read bytes: %d, from address: %u (%u), checksum: ", SPI_FLASH_SEC_SIZE, address, sector); string_append_string(dst, &sha_string); string_append(dst, "\n"); return(app_action_normal); }
/* Perform the SHA1 of the input string. We use this both for hashing script * bodies in order to obtain the Lua function name, and in the implementation * of redis.sha1(). * * 'digest' should point to a 41 bytes buffer: 40 for SHA1 converted into an * hexadecimal number, plus 1 byte for null term. */ void sha1hex(char *digest, char *script, size_t len) { SHA1_CTX ctx; unsigned char hash[20]; char *cset = "0123456789abcdef"; int j; SHA1Init(&ctx); SHA1Update(&ctx,(unsigned char*)script,len); SHA1Final(hash,&ctx); for (j = 0; j < 20; j++) { digest[j*2] = cset[((hash[j]&0xF0)>>4)]; digest[j*2+1] = cset[(hash[j]&0xF)]; } digest[40] = '\0'; }
void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) { if (ctx == NULL) return; switch (ctx->alg) { case CRYPTO_HASH_ALG_MD5: case CRYPTO_HASH_ALG_HMAC_MD5: MD5Update(&ctx->u.md5, data, len); break; case CRYPTO_HASH_ALG_SHA1: case CRYPTO_HASH_ALG_HMAC_SHA1: SHA1Update(&ctx->u.sha1, data, len); break; } }
void EncodeSHA1( char *hash_out, const char *str, int len ) { int i; SHA1_CTX ctx; uint8_t results[20]; char elem[4]; SHA1Init( &ctx ); SHA1Update( &ctx, (unsigned char*)str, len ); SHA1Final( results, &ctx ); hash_out[0] = 0; for( i = 0; i < 20; ++i ) { sprintf( elem, "%02x", results[i] ); strcat( hash_out, elem ); } }
bool Digest::put(const void *address, size_t size) { if(!context || !hashtype) return false; switch(*((char *)hashtype)) { case 'm': MD5Update((MD5_CTX*)context, (const unsigned char *)address, size); return true; case 's': SHA1Update((SHA1_CTX*)context, (const unsigned char *)address, size); return true; default: return false; } }
char * sha1 ( char * result, const char * str ) { SHA1_CTX * ctx; unsigned char buffer[20]; int i; ctx = malloc(sizeof(SHA1_CTX)); SHA1Init(ctx); SHA1Update(ctx, (unsigned char *) str, strlen(str)); SHA1Final(buffer, ctx); for(i = 0; i < 20; i++) sprintf(&result[i*2], "%02x", buffer[i]); if(ctx != NULL) free(ctx); }
static SQRESULT sq_fossil_sha1sum(HSQUIRRELVM v) { SQ_FUNC_VARS(v); const int hash_size = 20; const int buf_size = hash_size*2; char buf[buf_size+1]; SHA1Context ctx; SHA1Init(&ctx); for (int i = 2; i <= _top_; ++i) { SQ_GET_STRING(v, i, p); SHA1Update(&ctx, (const unsigned char *) p, p_size); } SHA1Final(&ctx, buf); sq_pushstring(v, buf, buf_size); return 1; }
void WEncodeSHA1( wchar_t *hash_out, const wchar_t *wstr, int len ) { int i; SHA1_CTX ctx; uint8_t results[20]; wchar_t elem[4]; SHA1Init( &ctx ); len *= sizeof( wchar_t ) / sizeof( unsigned char ); SHA1Update( &ctx, (unsigned char*)wstr, len ); SHA1Final( results, &ctx ); hash_out[0] = 0; for( i = 0; i < 20; ++i ) { swprintf( elem, 4, L"%02x", results[i] ); wcscat( hash_out, elem ); } }
int rl_multi_string_sha1(struct rlite *db, unsigned char digest[20], long number) { unsigned char *data; long datalen; SHA1_CTX sha; SHA1Init(&sha); void *tmp; rl_list *list; rl_list_iterator *iterator = NULL; int retval; RL_CALL(rl_read, RL_FOUND, db, &rl_data_type_list_long, number, &rl_list_type_long, &tmp, 0); list = tmp; RL_CALL(rl_list_iterator_create, RL_OK, db, &iterator, list, 1); long size = 0; while ((retval = rl_list_iterator_next(iterator, &tmp)) == RL_OK) { if (size == 0) { size = *(long *)tmp; rl_free(tmp); continue; } RL_CALL(rl_string_get, RL_OK, db, &data, *(long *)tmp); datalen = size > db->page_size ? db->page_size : size; SHA1Update(&sha, data, datalen); size -= datalen; rl_free(tmp); } iterator = NULL; if (retval != RL_END) { goto cleanup; } RL_CALL(rl_list_nocache_destroy, RL_OK, db, list); SHA1Final(digest, &sha); retval = RL_OK; cleanup: if (iterator) { rl_list_iterator_destroy(db, iterator); } return retval; }
std::string sha1_sum_data(const void* data, size_t len) { SHA1_CTX ctx; unsigned char hash[20]; const char *cset = "0123456789abcdef"; int j; SHA1Init(&ctx); SHA1Update(&ctx, (const unsigned char*)data, len); SHA1Final(hash, &ctx); char digest[40]; for (j = 0; j < 20; j++) { digest[j * 2] = cset[((hash[j] & 0xF0) >> 4)]; digest[j * 2 + 1] = cset[(hash[j] & 0xF)]; } return std::string(digest, 40); }
/* * Helper SHA1 digest update for mblk's. */ static int sha1_digest_update_mblk(SHA1_CTX *sha1_ctx, crypto_data_t *data) { off_t offset = data->cd_offset; size_t length = data->cd_length; mblk_t *mp; size_t cur_len; /* * Jump to the first mblk_t containing data to be digested. */ for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp); offset -= MBLKL(mp), mp = mp->b_cont) ; if (mp == NULL) { /* * The caller specified an offset that is larger than the * total size of the buffers it provided. */ return (CRYPTO_DATA_LEN_RANGE); } /* * Now do the digesting on the mblk chain. */ while (mp != NULL && length > 0) { cur_len = MIN(MBLKL(mp) - offset, length); SHA1Update(sha1_ctx, mp->b_rptr + offset, cur_len); length -= cur_len; offset = 0; mp = mp->b_cont; } if (mp == NULL && length > 0) { /* * The end of the mblk was reached but the length requested * could not be processed, i.e. The caller requested * to digest more data than it provided. */ return (CRYPTO_DATA_LEN_RANGE); } return (CRYPTO_SUCCESS); }
bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length) { switch (digest->type) { case CRYPTO_DIGEST_MD5: /* Doesn't return anything ... */ MD5Update(&digest->md5, (unsigned char *) data, length); return true; case CRYPTO_DIGEST_SHA1: int ret; if ((ret = SHA1Update(&digest->sha1, (const u_int8_t *) data, length)) == shaSuccess) { return true; } else { Jmsg1(NULL, M_ERROR, 0, _("SHA1Update() returned an error: %d\n"), ret); return false; } break; default: return false; } }
static qbool FMod_IsModelModified (const char *name, const int flags, const byte *buf, const size_t len) { int i; unsigned char hash[DIGEST_SIZE]; SHA1_CTX context; qbool found = false; SHA1Init (&context); SHA1Update (&context, (unsigned char *) buf, len); SHA1Final (hash, &context); for (i = 0; i < check_models_num; i++) { if (strcmp(name, check_models[i].name) == 0) { if (check_models[i].flags == flags) { found = true; break; } } } if (found) { if (memcmp(check_models[i].hash, hash, DIGEST_SIZE) == 0) { // original model return false; } else { check_models_hashes_entry_t *cur = check_models[i].hash_alt; while (cur) { if (memcmp(cur->hash, hash, DIGEST_SIZE) == 0) { // alternative legal model return false; } cur = cur->next; } } } // no match found return true; }
int GenerateBytes ( unsigned char *block, unsigned int blockLen, RANDOM_STRUCT *randStruct ) { SHA1_CTX context; unsigned int available, i; if (randStruct->bytesNeeded) return (0x0408); available = randStruct->outputAvailable; while (blockLen > available) { memcpy ((unsigned char *)block, (unsigned char *)&randStruct->output[20-available], available); block += available; blockLen -= available; /* generate new output */ SHA1Init (&context); SHA1Update (&context, randStruct->state, 20); SHA1Final (randStruct->output, &context); available = 16; /* increment state */ for (i = 0; i < 20; i++) if (randStruct->state[19-i]++) break; } memcpy ((unsigned char *)block, (unsigned char *)&randStruct->output[16-available], blockLen); randStruct->outputAvailable = available - blockLen; return (0); }
aes_encrypt_ctx *cpx_iv_aes_ctx(struct cpx *cpx) { if (ISSET(cpx->cpx_flags, CPX_IV_AES_CTX_INITIALIZED)) return &cpx->cpx_iv_aes_ctx; SHA1_CTX sha1ctxt; uint8_t digest[SHA_DIGEST_LENGTH]; /* Kiv */ /* First init the cp_cache_iv_key[] */ SHA1Init(&sha1ctxt); /* * We can only use this when the keys are generated in the AP; As a result * we only use the first 32 bytes of key length in the cache key */ SHA1Update(&sha1ctxt, cpx->cpx_cached_key, cpx->cpx_key_len); SHA1Final(digest, &sha1ctxt); cpx_set_aes_iv_key(cpx, digest); SET(cpx->cpx_flags, CPX_IV_AES_CTX_VFS); return &cpx->cpx_iv_aes_ctx; }
static int32 auth8651bGeneralApiTestItem(uint32 mode, uint8 * input, uint32 pktLen, uint8 * key, uint32 keyLen) { MD5_CTX md5Context; SHA1_CTX sha1Context; if(rtl8651b_authEngine(mode, input, pktLen, key, keyLen, asicDigest) == FAILED) return FAILED;//When authentication engine cannot calculate digest, the testing is surely failed authSim(mode, input, pktLen, key, keyLen, simDigest); if(memcmp(simDigest, asicDigest, (mode&0x1)? RTL8651B_SHA1_DIGEST_LENGTH: RTL8651B_MD5_DIGEST_LENGTH) != 0) { switch(mode) { case HASH_MD5: MD5Init(&md5Context); MD5Update(&md5Context, input, pktLen); MD5Final(swDigest, &md5Context); break; case HASH_SHA1: SHA1Init(&sha1Context); SHA1Update(&sha1Context, input, pktLen); SHA1Final(swDigest, &sha1Context); break; case HMAC_MD5: HMACMD5(input, pktLen, key, keyLen, swDigest); break; case HMAC_SHA1: HMACSHA1(input, pktLen, key, keyLen, swDigest); break; } if(memcmp(simDigest, swDigest, (mode&0x1)? RTL8651B_SHA1_DIGEST_LENGTH: RTL8651B_MD5_DIGEST_LENGTH) != 0) displayDigestMismatch(authModeString[mode], input, pktLen, key, keyLen, "SW", swDigest, "SIM", simDigest, (mode&0x1)? RTL8651B_SHA1_DIGEST_LENGTH: RTL8651B_MD5_DIGEST_LENGTH); else { displayDigestMismatch(authModeString[mode], input, pktLen, key, keyLen, "SIM", simDigest, "ASIC", asicDigest, (mode&0x1)? RTL8651B_SHA1_DIGEST_LENGTH: RTL8651B_MD5_DIGEST_LENGTH); triggerGpio(); //rtl8651b_authEngineData(mode, input, pktLen, key, keyLen); } return FAILED; } return SUCCESS; }
int sha1test(void) { SHA1_CTX sha; int fail; int i; int j; uint8_t digest[20]; uint8_t rdigest[20]; /* * Perform SHA-1 tests */ for (j = 0; j < 4; ++j) { fail = 0; (void) printf("Test #%d ", j+1); SHA1Init(&sha); for (i = 0; i < repeatcount[j]; ++i) { SHA1Update(&sha, (unsigned char *)testarray[j], strlen(testarray[j])); } SHA1Final(digest, &sha); getxdata(rdigest, resultarray[j], 20); if (bcmp(digest, rdigest, 20) != 0) { (void) printf("FAILED\n"); fail++; } else { (void) printf("PASSED\n"); } } return (fail); }
int sha1sum_file(const std::string& file, std::string& hash) { FILE *fp; if ((fp = fopen(file.c_str(), "rb")) == NULL) { return -1; } SHA1_CTX ctx; SHA1Init(&ctx); const uint32 buf_size = 65536; unsigned char buf[buf_size]; while (1) { int ret = fread(buf, 1, buf_size, fp); if (ret > 0) { SHA1Update(&ctx, buf, ret); } if (ret < (int)buf_size) { break; } } fclose(fp); unsigned char hashstr[20]; SHA1Final(hashstr, &ctx); char result[256]; uint32 offset = 0; for (uint32 i = 0; i < 20; i++) { int ret = sprintf(result + offset, "%02x", hashstr[i]); offset += ret; } hash = result; return 0; }
//可重用,用于唯一 id void getRandomHexChars(char *p, unsigned int len) { char *charset = "0123456789abcdef"; unsigned int j; /* Global state. */ static int seed_initialized = 0; static unsigned char seed[20]; /* The SHA1 seed, from /dev/urandom. */ static uint64_t counter = 0; /* The counter we hash with the seed. */ if (!seed_initialized) { /* Initialize a seed and use SHA1 in counter mode, where we hash * the same seed with a progressive counter. For the goals of this * function we just need non-colliding strings, there are no * cryptographic security needs. */ FILE *fp = fopen("/dev/urandom","r"); if (fp && fread(seed,sizeof(seed),1,fp) == 1) seed_initialized = 1; if (fp) fclose(fp); } if (seed_initialized) { while(len) { unsigned char digest[20]; SHA1_CTX ctx; unsigned int copylen = len > 20 ? 20 : len; SHA1Init(&ctx); SHA1Update(&ctx, seed, sizeof(seed)); SHA1Update(&ctx, (unsigned char*)&counter,sizeof(counter)); SHA1Final(digest, &ctx); counter++; memcpy(p,digest,copylen); /* Convert to hex digits. */ for (j = 0; j < copylen; j++) p[j] = charset[p[j] & 0x0F]; len -= copylen; p += copylen; } } else { /* If we can't read from /dev/urandom, do some reasonable effort * in order to create some entropy, since this function is used to * generate run_id and cluster instance IDs */ char *x = p; unsigned int l = len; struct timeval tv; pid_t pid = getpid(); /* Use time and PID to fill the initial array. */ gettimeofday(&tv,NULL); if (l >= sizeof(tv.tv_usec)) { memcpy(x,&tv.tv_usec,sizeof(tv.tv_usec)); l -= sizeof(tv.tv_usec); x += sizeof(tv.tv_usec); } if (l >= sizeof(tv.tv_sec)) { memcpy(x,&tv.tv_sec,sizeof(tv.tv_sec)); l -= sizeof(tv.tv_sec); x += sizeof(tv.tv_sec); } if (l >= sizeof(pid)) { memcpy(x,&pid,sizeof(pid)); l -= sizeof(pid); x += sizeof(pid); } /* Finally xor it with rand() output, that was already seeded with * time() at startup, and convert to hex digits. */ for (j = 0; j < len; j++) { p[j] ^= rand(); p[j] = charset[p[j] & 0x0F]; } } }
struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, size_t key_len) { struct crypto_hash *ctx; u8 k_pad[64]; u8 tk[20]; size_t i; ctx = os_zalloc(sizeof(*ctx)); if (ctx == NULL) return NULL; ctx->alg = alg; switch (alg) { case CRYPTO_HASH_ALG_MD5: MD5Init(&ctx->u.md5); break; case CRYPTO_HASH_ALG_SHA1: SHA1Init(&ctx->u.sha1); break; case CRYPTO_HASH_ALG_HMAC_MD5: if (key_len > sizeof(k_pad)) { MD5Init(&ctx->u.md5); MD5Update(&ctx->u.md5, key, key_len); MD5Final(tk, &ctx->u.md5); key = tk; key_len = 16; } os_memcpy(ctx->key, key, key_len); ctx->key_len = key_len; os_memcpy(k_pad, key, key_len); os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); for (i = 0; i < sizeof(k_pad); i++) k_pad[i] ^= 0x36; MD5Init(&ctx->u.md5); MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad)); break; case CRYPTO_HASH_ALG_HMAC_SHA1: if (key_len > sizeof(k_pad)) { SHA1Init(&ctx->u.sha1); SHA1Update(&ctx->u.sha1, key, key_len); SHA1Final(tk, &ctx->u.sha1); key = tk; key_len = 20; } os_memcpy(ctx->key, key, key_len); ctx->key_len = key_len; os_memcpy(k_pad, key, key_len); os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); for (i = 0; i < sizeof(k_pad); i++) k_pad[i] ^= 0x36; SHA1Init(&ctx->u.sha1); SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad)); break; default: os_free(ctx); return NULL; } return ctx; }