📄 shs1.c
字号:
* byte of padding to 0x80, on a little-endian machine set * the first four bytes to 0x00000080 * This is safe since there is always at least one byte or word free */ memset(data + count, 0, SHS1_CHUNKSIZE - count);#if CALC_BYTE_ORDER == LITTLE_ENDIAN if (state->bytes) { data[count] = 0x80; for (i=0; i < SHS1_CHUNKWORDS; ++i) { SWAP_B8_IN_B32(dig->data+i, dig->data+i); } } else { if (count % 4) { math_error("This should not happen in shs1Final"); /*NOTREACHED*/ } data[count + 3] = 0x80; }#else data[count] = 0x80;#endif if (count >= SHS1_CHUNKSIZE-8) { shs1Transform(dig->digest, dig->data); /* Now load another chunk with 56 bytes of padding */ memset(data, 0, SHS1_CHUNKSIZE-8); } /* * Append length in bits and transform * * We assume that bit count is a multiple of 8 because we have * only processed full bytes. */ highBitcount = dig->countHi; lowBitcount = dig->countLo; dig->data[SHS1_HIGH] = (highBitcount << 3) | (lowBitcount >> 29); dig->data[SHS1_LOW] = (lowBitcount << 3); shs1Transform(dig->digest, dig->data); dig->datalen = 0;}/* * shs1_chkpt - checkpoint a SHS1 state * * given: * state the state to checkpoint * * This function will ensure that the the hash chunk buffer is empty. * Any partially hashed data will be padded out with 0's and hashed. */static voidshs1_chkpt(HASH *state){ SHS1_INFO *dig = &state->h_union.h_shs1; /* digest state */#if CALC_BYTE_ORDER == LITTLE_ENDIAN unsigned int i;#endif /* * checkpoint if partial buffer exists */ if (dig->datalen > 0) { /* pad to the end of the chunk */ memset((USB8 *)dig->data + dig->datalen, 0, SHS1_CHUNKSIZE-dig->datalen);#if CALC_BYTE_ORDER == LITTLE_ENDIAN if (state->bytes) { for (i=0; i < SHS1_CHUNKWORDS; ++i) { SWAP_B8_IN_B32(dig->data+i, dig->data+i); } }#endif /* transform padded chunk */ shs1Transform(dig->digest, dig->data); SHS1COUNT(dig, SHS1_CHUNKSIZE-dig->datalen); /* empty buffer */ dig->datalen = 0; } return;}/* * shs1_note - note a special value * * given: * state the state to hash * special a special value (SHS1_HASH_XYZ) to note * * This function will note that a special value is about to be hashed. * Types include negative values, complex values, division, zero numeric * and array of HALFs. */static voidshs1_note(int special, HASH *state){ SHS1_INFO *dig = &state->h_union.h_shs1; /* digest state */ unsigned int i; /* * change state to reflect a special value */ dig->digest[0] ^= special; for (i=1; i < SHS1_DIGESTWORDS; ++i) { dig->digest[i] ^= (special + dig->digest[i-1] + i); } return;}/* * shs1_type - note a VALUE type * * given: * state the state to hash * type the VALUE type to note * * This function will note that a type of value is about to be hashed. * The type of a VALUE will be noted. For purposes of hash comparison, * we will do nothing with V_NUM and V_COM so that the other functions * can hash to the same value regardless of if shs1_value() is called * or not. We also do nothing with V_STR so that a hash of a string * will produce the same value as the standard hash function. */static voidshs1_type(int type, HASH *state){ SHS1_INFO *dig = &state->h_union.h_shs1; /* digest state */ unsigned int i; /* * ignore NUMBER and COMPLEX */ if (type == V_NUM || type == V_COM || type == V_STR) { return; } /* * change state to reflect a VALUE type */ dig->digest[0] += type; for (i=1; i < SHS1_DIGESTWORDS; ++i) { dig->digest[i] += ((type+i) ^ dig->digest[i-1]); } return;}/* * shs1_init_state - initialize a hash state structure for this hash * * given: * state - pointer to the hfunction element to initialize */voidshs1_init_state(HASH *state){ /* * initalize state */ state->hashtype = SHS1_HASH_TYPE; state->bytes = TRUE; state->update = shs1Update; state->chkpt = shs1_chkpt; state->note = shs1_note; state->type = shs1_type; state->final = shs1_final_state; state->cmp = shs1_cmp; state->print = shs1_print; state->base = SHS1_BASE; state->chunksize = SHS1_CHUNKSIZE; state->unionsize = sizeof(SHS1_INFO); /* * perform the internal init function */ memset((void *)&(state->h_union.h_shs), 0, sizeof(SHS1_INFO)); shs1Init(state); return;}/* * shs1_final_state - complete hash state and return a ZVALUE * * given: * state the state to complete and convert * * returns: * a ZVALUE representing the state */static ZVALUEshs1_final_state(HASH *state){ SHS1_INFO *dig = &state->h_union.h_shs1; /* digest state */ ZVALUE ret; /* return ZVALUE of completed hash state */ int i; /* * malloc and initialize if state is NULL */ if (state == NULL) { state = (HASH *)malloc(sizeof(HASH)); if (state == NULL) { math_error("cannot malloc HASH"); /*NOTREACHED*/ } shs1_init_state(state); } /* * complete the hash state */ shs1Final(state); /* * allocate storage for ZVALUE */ ret.len = SHS1_DIGESTSIZE/sizeof(HALF); ret.sign = 0; ret.v = alloc(ret.len); /* * load ZVALUE */#if BASEB == 16 && CALC_BYTE_ORDER == LITTLE_ENDIAN for (i=0; i < ret.len; i+=2) { ret.v[ret.len-i-1] = ((HALF*)dig->digest)[i+1]; ret.v[ret.len-i-2] = ((HALF*)dig->digest)[i]; }#else for (i=0; i < ret.len; ++i) { ret.v[ret.len-i-1] = ((HALF*)dig->digest)[i]; }#endif ztrim(&ret); /* * return ZVALUE */ return ret;}/* * shs1_cmp - compare two hash states * * given: * a first hash state * b second hash state * * returns: * TRUE => hash states are different * FALSE => hash states are the same */static intshs1_cmp(HASH *a, HASH *b){ /* * firewall and quick check */ if (a == b) { /* pointers to the same object */ return FALSE; } if (a == NULL || b == NULL) { /* one is NULL, so they differ */ return TRUE; } /* * compare data-reading modes */ if (a->bytes != b->bytes) return TRUE; /* * compare bit counts */ if (a->h_union.h_shs.countLo != b->h_union.h_shs.countLo || a->h_union.h_shs.countHi != b->h_union.h_shs.countHi) { /* counts differ */ return TRUE; } /* * compare pending buffers */ if (a->h_union.h_shs.datalen != b->h_union.h_shs.datalen) { /* buffer lengths differ */ return TRUE; } if (memcmp((USB8*)a->h_union.h_shs.data, (USB8*)b->h_union.h_shs.data, a->h_union.h_shs.datalen) != 0) { /* buffer contents differ */ return TRUE; } /* * compare digest */ return (memcmp((USB8*)(a->h_union.h_shs.digest), (USB8*)(b->h_union.h_shs.digest), SHS1_DIGESTSIZE) != 0);}/* * shs1_print - print a hash state * * given: * state the hash state to print */static voidshs1_print(HASH *state){ /* * form the hash value */ if (conf->calc_debug & CALCDBG_HASH_STATE) { char buf[DEBUG_SIZE+1]; /* hash value buffer */ /* * print numeric debug value * * NOTE: This value represents only the hash value as of * the last full update or finalization. Thus it * may NOT be the actual hash value. */ sprintf(buf, "sha1: 0x%08x%08x%08x%08x%08x data: %d octets", (int)state->h_union.h_shs1.digest[0], (int)state->h_union.h_shs1.digest[1], (int)state->h_union.h_shs1.digest[2], (int)state->h_union.h_shs1.digest[3], (int)state->h_union.h_shs1.digest[4], (int)state->h_union.h_shs1.datalen); math_str(buf); } else { math_str("sha1 hash state"); } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -