void random_add_noise(void *noise, int length) { unsigned char *p = noise; int i; if (!random_active) return; /* * This function processes HASHINPUT bytes into only HASHSIZE * bytes, so _if_ we were getting incredibly high entropy * sources then we would be throwing away valuable stuff. */ while (length >= (HASHINPUT - pool.incomingpos)) { memcpy(pool.incomingb + pool.incomingpos, p, HASHINPUT - pool.incomingpos); p += HASHINPUT - pool.incomingpos; length -= HASHINPUT - pool.incomingpos; SHATransform((word32 *) pool.incoming, (word32 *) pool.incomingb); for (i = 0; i < HASHSIZE; i++) { pool.pool[pool.poolpos++] ^= pool.incomingb[i]; if (pool.poolpos >= POOLSIZE) pool.poolpos = 0; } if (pool.poolpos < HASHSIZE) random_stir(); pool.incomingpos = 0; } memcpy(pool.incomingb + pool.incomingpos, p, length); pool.incomingpos += length; }
void SHA_Simple(void *p,WORD len,BYTE *output) { // SHA_State s; WORD i,t; ULONG c; BYTE *pBuff=p; for(i=0;i < len;i++) { t=i/4; if(i%4==0) { w[t]=0; } c=pBuff[i]; c <<=(3-(i%4))*8; w[t] |=c; HDCP_DEBUG_PRINTF2(("pBuff[%d]=%02X,c=%08lX,w[%d]=%08lX\n",(int)i,(int)pBuff[i],c,(int)t,w[t])); } t=i/4; if(i%4==0) { w[t]=0; } //c=0x80 << ((3-i%4)*24); c=0x80; c <<=((3-i%4)*8); w[t]|=c;t++; for(; t < 15;t++) { w[t]=0; } w[15]=len*8; for(i = 0 ; i < 16 ; i++) { HDCP_DEBUG_PRINTF2(("w[%d] = %08lX\n",i,w[i])); } SHATransform(VH); for(i=0;i < 5;i++) { output[i*4+3]=(BYTE)((VH[i]>>24)&0xFF); output[i*4+2]=(BYTE)((VH[i]>>16)&0xFF); output[i*4+1]=(BYTE)((VH[i]>>8)&0xFF); output[i*4+0]=(BYTE)(VH[i]&0xFF); } }
void random_add_noise(void *noise, int length) { unsigned char *p = noise; while (length >= (HASHINPUT - pool.incomingpos)) { memcpy(pool.incomingb + pool.incomingpos, p, HASHINPUT - pool.incomingpos); p += HASHINPUT - pool.incomingpos; length -= HASHINPUT - pool.incomingpos; SHATransform((word32 *)pool.incoming, (word32 *)pool.incomingb); pool.incomingpos = 0; } memcpy(pool.incomingb + pool.incomingpos, p, length); pool.incomingpos += length; }
static void random_stir(void) { word32 block[HASHINPUT / sizeof(word32)]; word32 digest[HASHSIZE / sizeof(word32)]; int i, j, k; /* * noise_get_light will call random_add_noise, which may call * back to here. Prevent recursive stirs. */ if (pool.stir_pending) return; pool.stir_pending = TRUE; noise_get_light(random_add_noise); SHATransform((word32 *) pool.incoming, (word32 *) pool.incomingb); pool.incomingpos = 0; /* * Chunks of this code are blatantly endianness-dependent, but * as it's all random bits anyway, WHO CARES? */ memcpy(digest, pool.incoming, sizeof(digest)); /* * Make two passes over the pool. */ for (i = 0; i < 2; i++) { /* * We operate SHA in CFB mode, repeatedly adding the same * block of data to the digest. But we're also fiddling * with the digest-so-far, so this shouldn't be Bad or * anything. */ memcpy(block, pool.pool, sizeof(block)); /* * Each pass processes the pool backwards in blocks of * HASHSIZE, just so that in general we get the output of * SHA before the corresponding input, in the hope that * things will be that much less predictable that way * round, when we subsequently return bytes ... */ for (j = POOLSIZE; (j -= HASHSIZE) >= 0;) { /* * XOR the bit of the pool we're processing into the * digest. */ for (k = 0; k < sizeof(digest) / sizeof(*digest); k++) digest[k] ^= ((word32 *) (pool.pool + j))[k]; /* * Munge our unrevealed first block of the pool into * it. */ SHATransform(digest, block); /* * Stick the result back into the pool. */ for (k = 0; k < sizeof(digest) / sizeof(*digest); k++) ((word32 *) (pool.pool + j))[k] = digest[k]; } } /* * Might as well save this value back into `incoming', just so * there'll be some extra bizarreness there. */ SHATransform(digest, block); memcpy(pool.incoming, digest, sizeof(digest)); pool.poolpos = sizeof(pool.incoming); pool.stir_pending = FALSE; }