示例#1
0
void sha1_final(SHA1_CONTEXT *hd)  
{  
    u32 t, msb, lsb;  
    unsigned char *p;  
  
    sha1_write(hd, NULL, 0); /* flush */;  
  
    t = hd->nblocks;  
    /* multiply by 64 to make a byte count */  
    lsb = t << 6;  
    msb = t >> 26;  
    /* add the count */  
    t = lsb;  
    if( (lsb += hd->count) < t )  
        msb++;  
    /* multiply by 8 to make a bit count */  
    t = lsb;  
    lsb <<= 3;  
    msb <<= 3;  
    msb |= t >> 29;  
  
    if( hd->count < 56 ) { /* enough room */  
        hd->buf[hd->count++] = 0x80; /* pad */  
        while( hd->count < 56 )  
            hd->buf[hd->count++] = 0;  /* pad */  
    }  
    else { /* need one extra block */  
        hd->buf[hd->count++] = 0x80; /* pad character */  
        while( hd->count < 64 )  
            hd->buf[hd->count++] = 0;  
        sha1_write(hd, NULL, 0);  /* flush */;  
        memset(hd->buf, 0, 56 ); /* fill next block with zeroes */  
    }  
    /* append the 64 bit count */  
    hd->buf[56] = msb >> 24;  
    hd->buf[57] = msb >> 16;  
    hd->buf[58] = msb >>  8;  
    hd->buf[59] = msb       ;  
    hd->buf[60] = lsb >> 24;  
    hd->buf[61] = lsb >> 16;  
    hd->buf[62] = lsb >>  8;  
    hd->buf[63] = lsb       ;  
    transform( hd, hd->buf );  
  
    p = hd->buf;  
#ifdef BIG_ENDIAN_HOST  
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)  
#else /* little endian */  
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
        *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)  
#endif  
    X(0);  
    X(1);  
    X(2);  
    X(3);  
    X(4);  
#undef X  
}  
示例#2
0
/* API */
char *oauth_sign_hmac_sha1_raw (const char *m, const size_t ml, const char *k, const size_t kl) {
	sha1nfo s;
	sha1_initHmac(&s, (const uint8_t*) k, kl);
	sha1_write(&s, m, ml);
	unsigned char *digest = sha1_resultHmac(&s);
  return oauth_encode_base64(HASH_LENGTH, digest);
}
示例#3
0
文件: chord.c 项目: willzxd/Chord
/**
Get the Node ID
*/
long getId(char *str){

	sha1nfo i;

	char ipPort[30], tmp[30];
	if (strcmp(str, "\0") == 0){
		//connect ip and port
		strcpy (ipPort, current->ip);
    	strcat (ipPort,": ");
    	sprintf(tmp, "%d", current->port);
    	strcat (ipPort, tmp);
	} else
		strcpy(ipPort, str);

	sha1_init(&i);
	sha1_write(&i, ipPort, strlen(ipPort));


	uint8_t* hash = sha1_result(&i);
	uint32_t b0 = hash[0] | hash[1] << 8 | hash[2] << 16 | hash[3] << 24;
	uint32_t b1 = hash[4] | hash[5] << 8 | hash[6] << 16 | hash[7] << 24;
	uint32_t b2 = hash[8] | hash[9] << 8 | hash[10] << 16 | hash[11] << 24;
	uint32_t b3 = hash[12] | hash[13] << 8 | hash[14] << 16 | hash[15] << 24;
	uint32_t b4 = hash[16] | hash[17] << 8 | hash[18] << 16 | hash[19] << 24;
	
	long id;
	id = b0 ^ b1 ^ b2 ^ b3 ^ b4;
	return id;
}
示例#4
0
/* Update the message digest with the contents  
 * of INBUF with length INLEN.  
 */  
void sha1_write( SHA1_CONTEXT *hd, unsigned char *inbuf, size_t inlen)  
{  
    if( hd->count == 64 ) { /* flush the buffer */  
        transform( hd, hd->buf );  
        hd->count = 0;  
        hd->nblocks++;  
    }  
    if( !inbuf )  
        return;  
    if( hd->count ) {  
        for( ; inlen && hd->count < 64; inlen-- )  
            hd->buf[hd->count++] = *inbuf++;  
        sha1_write( hd, NULL, 0 );  
        if( !inlen )  
            return;  
    }  
  
    while( inlen >= 64 ) {  
        transform( hd, inbuf );  
        hd->count = 0;  
        hd->nblocks++;  
        inlen -= 64;  
        inbuf += 64;  
    }  
    for( ; inlen && hd->count < 64; inlen-- )  
        hd->buf[hd->count++] = *inbuf++;  
}  
示例#5
0
文件: cconf.c 项目: fiktivkod/dlight
int cconf_write(int fd, struct cconf *c) {

	int i;
	SHA_CTX ctx;
	struct cconf_header hdr;

	hdr.signature = htonl(CCONF_SIGNATURE);
	hdr.version = htonl(1);

	SHA1_Init(&ctx);
	SHA1_Update(&ctx, &hdr, offsetof(struct cconf_header, crc));

	/* leave room for the header to be written later as CRC
	   will be calculated as we write the rest of the data */
	lseek(fd, sizeof(hdr), SEEK_SET);

	/* put number of targets */
	sha1_write_int(&ctx, fd, c->nr);

	for(i = 0; i < c->nr; i++) {
		int j;
		struct target *target = c->target + i;

		if (!target->src)
			return -1;

		sha1_write(&ctx, fd, target->src, strsize(target->src));

		/* write number of filters */
		sha1_write_int(&ctx, fd, target->nr);

		for(j=0; j < target->nr; j++) {
			struct filter *f = &target->filter[j];

			sha1_write(&ctx, fd, f->pattern, strsize(f->pattern));
			sha1_write(&ctx, fd, f->dest, strsize(f->dest));
		}
	}

	SHA1_Final(hdr.crc, &ctx);

	/* write header */
	lseek(fd, 0, SEEK_SET);
	sha1_write(&ctx, fd, &hdr, sizeof(hdr));

	return 0;
}
示例#6
0
文件: common.c 项目: hbhdytf/secshare
static void rand_refill()
{
        void*rh;
        int i,r;
        byte*b;

        if(pool==NULL)init_seth_rand();

        ppos=0;
        /*we assume each rand() call will give us 8 random bits (it probably
        has more, but you can't have too much random).*/
        rh=sha1_new();
        /*make the period longer by making the next block dependend on the current one*/
        sha1_write(rh,pool,20);
        /*add the random to the soup*/
        for(i=0;i<20;i++){
                r=rand();
                sha1_write(rh,(void*)&r,sizeof(r));
        }
        /*fill the pool*/
        b=sha1_get(rh);
        memcpy(pool,b,20);
        sha1_close(rh);
}
示例#7
0
static int ICACHE_FLASH_ATTR createWsAcceptKey(const char *key, char *buffer, int bufferSize) {
	sha1nfo s;

	char concatenatedBuffer[512];
	concatenatedBuffer[0] = '\0';
	//concatenate the key and the GUID
	os_strcat(concatenatedBuffer, key);
	os_strcat(concatenatedBuffer, WS_GUID);

	//build the sha1 hash
	sha1_init(&s);
	sha1_write(&s, concatenatedBuffer, strlen(concatenatedBuffer));
	uint8_t *hash = sha1_result(&s);

	return base64_encode(20, hash, bufferSize, buffer);
}
示例#8
0
char *oauth_body_hash_file(char *filename) {
  FILE *F= fopen(filename, "r");
  if (!F) return NULL;

  size_t len=0;
  char fb[BUFSIZ];
	sha1nfo s;
	sha1_init(&s);

  while (!feof(F) && (len=fread(fb,sizeof(char),BUFSIZ, F))>0) {
		sha1_write(&s, fb, len);
	}
  fclose(F);

  unsigned char *dgst = xmalloc(HASH_LENGTH*sizeof(char)); // oauth_body_hash_encode frees the digest..
  memcpy(dgst, sha1_result(&s), HASH_LENGTH);
  return oauth_body_hash_encode(HASH_LENGTH, dgst);
}
示例#9
0
文件: main.c 项目: j43ster/pw_crack
int crack_password_permutations(uint8_t* hash_ptr, int current_len, char* solution, int ends_with) {

   sha1nfo current_hash;
   uint8_t *current_hash_ptr;
   char    current_pw[100];
   uint8_t current_idxs[100]; // index into charset
   int i;

   // initialize
   for (i = 0; i < 100; i++) {
      current_pw[i] = 0;
      current_idxs[i] = 0;
   }

   for (i = 0; i < current_len; i++) {
      current_pw[0] = charset[0];
   }
   
   current_pw[current_len-1] = charset[ends_with];
   //if (my_id == id)
    //  printf("start: %s\n", current_pw);

   do { // loops over password space for given password length
      //printf("%s\n", current_pw);
      // hash current password attempt
      sha1_init(&current_hash);
      sha1_write(&current_hash, current_pw, strlen(current_pw));
      current_hash_ptr = sha1_result(&current_hash);

      // check if equal to hash we are cracking
      if (strncmp((char *)hash_ptr, (char *)current_hash_ptr, HASH_LENGTH) == 0) {

         strncpy(solution, current_pw, current_len);

         printf("found a password with a matching hash!\n");
         printHash(current_hash_ptr);
         printf("password is: %s\n", current_pw);

         return 1;
      }
   } while (next_password(current_pw, current_idxs, current_len - 1));

   return 0;
}
示例#10
0
/* Update the message digest with the contents
 * of INBUF with length INLEN.
 */
static void
sha1_write( void *context, const void *inbuf_arg, size_t inlen)
{
  const unsigned char *inbuf = inbuf_arg;
  SHA1_CONTEXT *hd = context;
  size_t nblocks;

  if (hd->count == 64)  /* Flush the buffer. */
    {
      TRANSFORM( hd, hd->buf, 1 );
      _gcry_burn_stack (88+4*sizeof(void*));
      hd->count = 0;
      hd->nblocks++;
    }
  if (!inbuf)
    return;

  if (hd->count)
    {
      for (; inlen && hd->count < 64; inlen--)
        hd->buf[hd->count++] = *inbuf++;
      sha1_write (hd, NULL, 0);
      if (!inlen)
        return;
    }

  nblocks = inlen / 64;
  if (nblocks)
    {
      TRANSFORM (hd, inbuf, nblocks);
      hd->count = 0;
      hd->nblocks += nblocks;
      inlen -= nblocks * 64;
      inbuf += nblocks * 64;
    }
  _gcry_burn_stack (88+4*sizeof(void*));

  /* Save remaining bytes.  */
  for (; inlen && hd->count < 64; inlen--)
    hd->buf[hd->count++] = *inbuf++;
}
示例#11
0
文件: main.c 项目: j43ster/pw_crack
void run_master(int me, int nprocs, int argc, char** argv) {

   sha1nfo hash;
   uint8_t *hash_ptr;
   const char *pw = "h678a";
   int i;
   int num_workers = nprocs - 1;

   // compute hash
   sha1_init(&hash);
   sha1_write(&hash, pw, strlen(pw)); 
   hash_ptr = sha1_result(&hash);
   //printHash(hash_ptr);

   // send hash
   for (i = 0; i < num_workers; i++) {
      MPI_Send((void *)(hash_ptr), HASH_LENGTH, MPI_UNSIGNED_CHAR, i + 1, 0, MPI_COMM_WORLD);
   } 

   // send work
   for (i = 0; i < strlen(charset); i++) {

   }
}
示例#12
0
// The rest is added for LibFuzzer
void ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out) {
  sha1nfo s;
  sha1_init(&s);
  sha1_write(&s, (const char*)Data, Len);
  memcpy(Out, sha1_result(&s), HASH_LENGTH);
}
示例#13
0
/*
 * 	Generate a #PKCS1.5 padded message
 * 	The output string buffer should have enough memory to incorporate the padding.
 */
int pkcs1_v1_5_generate(unsigned char *output, const unsigned char *msg, const size_t msg_len, const size_t block_len, enum pkcs1_v1_5_msg_type msg_type, const enum pkcs1_v1_5_sign_hash_method h_method)
{
	size_t pad_len, hash_len;
	uint8_t sha256_buf[SHA256_HASH_SIZE];
	struct sha256nfo sha256_h;
	struct sha1nfo sha1_h;
	char *hash_name;


	memset(output, 0, block_len);

	/* 
	 *  Hash type
	 */
	switch(h_method)
	{
	case SHA1:
		hash_len = SHA1_HASH_LENGTH;
		hash_name = PKCS1_SIGN_HASH_METHOD_SHA_1;
		break;
	case SHA256:
		hash_len =	SHA256_HASH_SIZE;
		hash_name = PKCS1_SIGN_HASH_METHOD_SHA_256;
		break;
	default:
		return -1;
	}

	if (3 + strlen(hash_name) + hash_len > block_len)
		return 0x01;

	
	/* Padding */
	output[0] = 0x00;
	switch (msg_type)
	{
	case pkcs1_signature:
		output[1] = PKCS1_BT_01;
		pad_len = block_len - strlen(hash_name) - hash_len - (3);
		memset(output + 2, 0xff, pad_len);
		break;
	case pkcs1_msg:
		output[1] = PKCS1_BT_02;
		pad_len = block_len - msg_len - (3);
		pkcs1_v1_5_gen_rpadding(output + 2, pad_len);
		break;
	}
	output[2 + pad_len] = 0x00;


	/* 
	 *  Hash value
	 */
    switch (msg_type)
	{
	case pkcs1_signature:
		memcpy(output +  3 + pad_len, hash_name, strlen(hash_name));
		switch(h_method)
		{
		case SHA1:
			sha1_init(&sha1_h);
			sha1_write(&sha1_h, (char*) msg, msg_len); 
			memcpy(output  + 3 + pad_len + strlen(hash_name), sha1_result(&sha1_h), SHA1_HASH_LENGTH);
			break;

		case SHA256:
			sha256_init(&sha256_h);
			sha256_write(&sha256_h, (uint8_t*) msg, msg_len); 
			sha256_result(&sha256_h, sha256_buf);

			memcpy(output  + 3 + pad_len + strlen(hash_name), sha256_buf, SHA256_HASH_SIZE);
			break;
		default:
			return -1;
		}
		break;

	case pkcs1_msg:
		memcpy(output + 3 + pad_len, msg, msg_len);
		break;
	}


	return 0x00;
}
示例#14
0
文件: main.c 项目: lucasg/Cryptopals
/*
 *  The liboauth sha1 is too intelligent : it detect the platform's endianess and
 *  return a coherent result, independant from endian. However it's much more simple
 *  to work in bitstream (i.e. big endian) when it's come to padding. Of course on a 
 *  real platform you don't have access to the endianess, therefore you have to test
 *  both cases.
 */
int main (int argc, char **argv) {
	
	uint8_t basic_hash[SHA1_HASH_LENGTH],
			pad_basic_oauth[2*SHA1_BLOCK_LENGTH];
	size_t i,padlen,
		   basic_oauthlen = strlen(basic_oauth) + strlen(secret), // Supposedly known by the attacker.
		   padded_basic_oauthlen;
	uint8_t *padded_basic_oauth;

	// SHA pad test
	sha1_utils_test_pad();

	// Break SHA-1
	printf("Exercice : break keyed SHA-1\n");

		// Create basic token	
	sha1_utils_keyed_mac(basic_hash, (uint8_t*) secret, strlen(secret), (uint8_t*) basic_oauth, strlen(basic_oauth));
	printf("Basic auth hash :");
	sha1_utils_printHash(basic_hash);

		// Compute pad 
	sha1_utils_md_pad(pad_basic_oauth, &padlen, (uint8_t*) basic_oauth, basic_oauthlen);
	padded_basic_oauthlen = strlen(basic_oauth) + padlen + strlen(admin_key);

	padded_basic_oauth = malloc(padded_basic_oauthlen*sizeof(uint8_t));
	if (NULL == padded_basic_oauth)
		return 0x01;

	sha1_utils_concat(padded_basic_oauth, (uint8_t*) basic_oauth, strlen(basic_oauth), pad_basic_oauth, padlen);	
	
		// check if padding works
	struct sha1nfo padded_basic_s;
	sha1_init(&padded_basic_s);
	sha1_write(&padded_basic_s,  secret, strlen(secret));
	sha1_write(&padded_basic_s,  (char*) padded_basic_oauth, strlen(basic_oauth) + padlen);

	printf("Basic padded auth hash :");
	sha1_utils_print_array((uint8_t*) padded_basic_s.state, SHA1_HASH_LENGTH, SWAP_ENDIAN );


		//SHA-1 "fixation"
	struct sha1nfo s;
	s.state[0] =  htonl(((uint32_t*) basic_hash)[0]);
	s.state[1] =  htonl(((uint32_t*) basic_hash)[1]);
	s.state[2] =  htonl(((uint32_t*) basic_hash)[2]);
	s.state[3] =  htonl(((uint32_t*) basic_hash)[3]);
	s.state[4] =  htonl(((uint32_t*) basic_hash)[4]);
	s.byteCount = strlen(secret) + strlen(basic_oauth) + padlen;
	s.bufferOffset = 0;
	

		// Add new data
	sha1_write(&s, admin_key, strlen(admin_key));
	uint8_t *result = sha1_result(&s);

	for (i = 0; i < strlen(admin_key); i++)
		padded_basic_oauth[i + strlen(basic_oauth) + padlen] =  admin_key[i];

		// Check signature
	if (test_sha1_sig(padded_basic_oauth, padded_basic_oauthlen, result))
	{
		printf("Valid command : "); 	
		write(1, padded_basic_oauth, padded_basic_oauthlen);
		printf("\n");
	}


	free(padded_basic_oauth);
	return 0;
}
示例#15
0
static int load_split_rom_parts(struct archive *archive, int *chip_list, struct rom_info *rom_info,
                                 uint8_t **bufferp, size_t *sizep)
{
	uint8_t *buffer;
	uint8_t *ptr;
	size_t size;
	off_t offsets[MAX_ROMS];
	int file_list[MAX_ROMS];
	int num_chips;
	int status;
	int i;

	size = 0;

	num_chips = rom_info->prg_size_count + rom_info->chr_size_count;

	for (i = 0; i < MAX_ROMS; i++)
		file_list[i] = -1;

	status = 0;
	for (i = 0; i < num_chips; i++) {
		int j;

		for (j = 0; j < archive->file_list->count; j++) {
			if (chip_list[j] == i) {
				offsets[i] = size;
				size += archive->file_list->entries[j].size;
				break;
			}
		}
	}

	buffer = malloc(INES_HEADER_SIZE + size);
	if (!buffer) {
		return -1;
	}

	ptr = buffer + INES_HEADER_SIZE;

	for (i = 0; i < num_chips; i++) {
		int j;

		for (j = 0; j < archive->file_list->count; j++) {
			if (chip_list[j] == i) {
				sha1nfo sha1;
				uint8_t *result;

				file_list[i] = j;
				status = archive_read_file_by_index(archive, file_list[i], ptr);
				if (status) {
					free(buffer);
					return -1;
				}

				/* Validate each chip's SHA1, if present. If it doesn't match,
				   then move on to the next match for that chip in the archive.
				 */

				if ((i < rom_info->prg_size_count) && rom_info->prg_sha1_count) {
					sha1_init(&sha1);
					sha1_write(&sha1, (char *)ptr,
					           archive->file_list->entries[file_list[i]].size);
					result = sha1_result(&sha1);
					if (memcmp(result, rom_info->prg_sha1[i], 20) != 0) {
						continue;
					}
				} else if (rom_info->chr_sha1_count) {
					sha1_init(&sha1);
					sha1_write(&sha1, (char *)ptr,
					           archive->file_list->entries[file_list[i]].size);
					result = sha1_result(&sha1);
					if (memcmp(result, rom_info->chr_sha1[i -
					                   rom_info->prg_size_count], 20) != 0) {
						continue;
					}
				}

				ptr += archive->file_list->entries[file_list[i]].size;
				break;
			}
		}

		if (j == archive->file_list->count) {
			status = -1;
			break;
		}
	}

	if (status < 0) {
		if (bufferp)
			*bufferp = NULL;
		return 0;
	}

	status = -1;

	for (i = 0; (i < MAX_ROMS) && (file_list[i] >= 0); i++) {
		uint8_t *ptr;

		ptr = buffer + INES_HEADER_SIZE + offsets[i];
		status = archive_read_file_by_index(archive, file_list[i], ptr);

		if (status)
			break;
	}

	if (status) {
		free(buffer);
		if (bufferp)
			*bufferp = NULL;
		return 0;
	}

	if (sizep) {
		*sizep = size + INES_HEADER_SIZE;
	}

	*bufferp = buffer;
	return 0;
}
int main (int argc, char **argv) {
  uint32_t a;
  sha1nfo s;

  printf("sizeof(sha1nfo)=%d\n\n", sizeof(sha1nfo));

  // SHA tests
  printf("Test: FIPS 180-2 C.1 and RFC3174 7.3 TEST1\n");
  printf("Expect:a9993e364706816aba3e25717850c26c9cd0d89d\n");
  printf("Result:");
  sha1_init(&s);
  sha1_write(&s, "abc", 3);
  printHash(sha1_result(&s));
  printf("\n\n");

  printf("Test: FIPS 180-2 C.2 and RFC3174 7.3 TEST2\n");
  printf("Expect:84983e441c3bd26ebaae4aa1f95129e5e54670f1\n");
  printf("Result:");
  sha1_init(&s);
  sha1_write(&s, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
  printHash(sha1_result(&s));
  printf("\n\n");

  printf("Test: RFC3174 7.3 TEST4\n");
  printf("Expect:dea356a2cddd90c7a7ecedc5ebb563934f460452\n");
  printf("Result:");
  sha1_init(&s);
  for (a=0; a<80; a++) sha1_write(&s, "01234567", 8);
  printHash(sha1_result(&s));
  printf("\n\n");

  // HMAC tests
  printf("Test: FIPS 198a A.1\n");
  printf("Expect:4f4ca3d5d68ba7cc0a1208c9c61e9c5da0403c0a\n");
  printf("Result:");
  sha1_initHmac(&s, hmacKey1, 64);
  sha1_write(&s, "Sample #1",9);
  printHash(sha1_resultHmac(&s));
  printf("\n\n");

  printf("Test: FIPS 198a A.2\n");
  printf("Expect:0922d3405faa3d194f82a45830737d5cc6c75d24\n");
  printf("Result:");
  sha1_initHmac(&s, hmacKey2, 20);
  sha1_write(&s, "Sample #2", 9);
  printHash(sha1_resultHmac(&s));
  printf("\n\n");

  printf("Test: FIPS 198a A.3\n");
  printf("Expect:bcf41eab8bb2d802f3d05caf7cb092ecf8d1a3aa\n");
  printf("Result:");
  sha1_initHmac(&s, hmacKey3,100);
  sha1_write(&s, "Sample #3", 9);
  printHash(sha1_resultHmac(&s));
  printf("\n\n");

  printf("Test: FIPS 198a A.4\n");
  printf("Expect:9ea886efe268dbecce420c7524df32e0751a2a26\n");
  printf("Result:");
  sha1_initHmac(&s, hmacKey4,49);
  sha1_write(&s, "Sample #4", 9);
  printHash(sha1_resultHmac(&s));
  printf("\n\n");

  // Long tests
  printf("Test: FIPS 180-2 C.3 and RFC3174 7.3 TEST3\n");
  printf("Expect:34aa973cd4c4daa4f61eeb2bdbad27316534016f\n");
  printf("Result:");
  sha1_init(&s);
  for (a=0; a<1000000; a++) sha1_writebyte(&s, 'a');
  printHash(sha1_result(&s));

  // liang: 65536 zeros
  printf("\n\n");
  printf("Test: 65536 zeros\n");
  printf("Expect:1adc95bebe9eea8c112d40cd04ab7a8d75c4f961\n");
  printf("Result:");
  sha1_init(&s);
  for (a=0; a<65536; a++) sha1_writebyte(&s, 0);
  printHash(sha1_result(&s));

  // test liang_zhash
  printf("\n\n");
  printf("Test: 65536 zeros\n");
  printf("Expect:1adc95bebe9eea8c112d40cd04ab7a8d75c4f961\n");
  printf("Result:");
  uint8_t hash[20];
  char buf[65536];
  for(a=0; a<65536; a++) buf[a]=0;
  liang_zhash((const uint8_t *)buf, 65536, hash);
  printHash(hash);
  
  return 0;
}
示例#17
0
static void
sha1_final(void *context)
{
  SHA1_CONTEXT *hd = context;

  u32 t, msb, lsb;
  unsigned char *p;

  sha1_write(hd, NULL, 0); /* flush */;

  t = hd->nblocks;
  /* multiply by 64 to make a byte count */
  lsb = t << 6;
  msb = t >> 26;
  /* add the count */
  t = lsb;
  if( (lsb += hd->count) < t )
    msb++;
  /* multiply by 8 to make a bit count */
  t = lsb;
  lsb <<= 3;
  msb <<= 3;
  msb |= t >> 29;

  if( hd->count < 56 )  /* enough room */
    {
      hd->buf[hd->count++] = 0x80; /* pad */
      while( hd->count < 56 )
        hd->buf[hd->count++] = 0;  /* pad */
    }
  else  /* need one extra block */
    {
      hd->buf[hd->count++] = 0x80; /* pad character */
      while( hd->count < 64 )
        hd->buf[hd->count++] = 0;
      sha1_write(hd, NULL, 0);  /* flush */;
      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
    }
  /* append the 64 bit count */
  hd->buf[56] = msb >> 24;
  hd->buf[57] = msb >> 16;
  hd->buf[58] = msb >>  8;
  hd->buf[59] = msb	   ;
  hd->buf[60] = lsb >> 24;
  hd->buf[61] = lsb >> 16;
  hd->buf[62] = lsb >>  8;
  hd->buf[63] = lsb	   ;
  TRANSFORM( hd, hd->buf, 1 );
  _gcry_burn_stack (88+4*sizeof(void*));

  p = hd->buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
#else /* little endian */
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;	 \
                  *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
#endif
  X(0);
  X(1);
  X(2);
  X(3);
  X(4);
#undef X

}
示例#18
0
文件: DiscWii.cpp 项目: AxioDL/nod
    uint64_t buildFromDirectory(const SystemChar* dirIn,
                                const SystemChar* dolIn,
                                const SystemChar* apploaderIn,
                                const SystemChar* partHeadIn)
    {
        /* Read head and validate key members */
        std::unique_ptr<IFileIO> ph = NewFileIO(partHeadIn);

        uint8_t tkey[16];
        {
            if (ph->beginReadStream(0x1BF)->read(tkey, 16) != 16)
                LogModule.report(logvisor::Fatal, _S("unable to read title key from %s"), partHeadIn);
        }

        uint8_t tkeyiv[16] = {};
        {
            if (ph->beginReadStream(0x1DC)->read(tkeyiv, 8) != 8)
                LogModule.report(logvisor::Fatal, _S("unable to read title key IV from %s"), partHeadIn);
        }

        uint8_t ccIdx;
        {
            if (ph->beginReadStream(0x1F1)->read(&ccIdx, 1) != 1)
                LogModule.report(logvisor::Fatal, _S("unable to read common key index from %s"), partHeadIn);
            if (ccIdx > 1)
                LogModule.report(logvisor::Fatal, _S("common key index may only be 0 or 1"));
        }

        uint32_t tmdSz;
        {
            if (ph->beginReadStream(0x2A4)->read(&tmdSz, 4) != 4)
                LogModule.report(logvisor::Fatal, _S("unable to read TMD size from %s"), partHeadIn);
            tmdSz = SBig(tmdSz);
        }

        uint64_t h3Off;
        {
            uint32_t h3Ptr;
            if (ph->beginReadStream(0x2B4)->read(&h3Ptr, 4) != 4)
                LogModule.report(logvisor::Fatal, _S("unable to read H3 pointer from %s"), partHeadIn);
            h3Off = uint64_t(SBig(h3Ptr)) << 2;
        }

        uint64_t dataOff;
        {
            uint32_t dataPtr;
            if (ph->beginReadStream(0x2B8)->read(&dataPtr, 4) != 4)
                LogModule.report(logvisor::Fatal, _S("unable to read data pointer from %s"), partHeadIn);
            dataOff = uint64_t(SBig(dataPtr)) << 2;
        }
        m_userOffset = dataOff;

        std::unique_ptr<uint8_t[]> tmdData(new uint8_t[tmdSz]);
        if (ph->beginReadStream(0x2C0)->read(tmdData.get(), tmdSz) != tmdSz)
            LogModule.report(logvisor::Fatal, _S("unable to read TMD from %s"), partHeadIn);

        /* Copy partition head up to H3 table */
        std::unique_ptr<IFileIO::IWriteStream> ws = m_parent.getFileIO().beginWriteStream(m_baseOffset);
        {
            uint64_t remCopy = h3Off;

            uint8_t copyBuf[8192];
            std::unique_ptr<IFileIO::IReadStream> rs = ph->beginReadStream();
            while (remCopy)
            {
                size_t rdBytes = rs->read(copyBuf, std::min(size_t(8192), size_t(remCopy)));
                if (rdBytes)
                {
                    ws->write(copyBuf, rdBytes);
                    remCopy -= rdBytes;
                    continue;
                }
                for (size_t i=0 ; i<remCopy ; ++i)
                    ws->write("", 1);
                break;
            }
        }

        /* Prepare crypto pass */
        m_aes->setKey(COMMON_KEYS[ccIdx]);
        m_aes->decrypt(tkeyiv, tkey, tkey, 16);
        m_aes->setKey(tkey);

        {
            /* Assemble partition data */
            std::unique_ptr<IPartWriteStream> cws = beginWriteStream(0x1F0000);
            bool result = DiscBuilderBase::PartitionBuilderBase::buildFromDirectory(*cws, dirIn, dolIn, apploaderIn);
            if (!result)
                return 0;

            /* Pad out user area to nearest cleartext sector */
            m_curUser = cws->position();
            uint64_t curUserRem = m_curUser % 0x1F0000;
            if (curUserRem)
            {
                curUserRem = 0x1F0000 - curUserRem;
                for (size_t i=0 ; i<curUserRem ; ++i)
                    cws->write("\xff", 1);
                m_curUser += curUserRem;
            }

            /* Begin crypto write and add content header */
            cws = beginWriteStream(0);
            Header header(m_gameID, m_gameTitle.c_str(), true, 0, 0, 0);
            header.write(*cws);

            /* Get Apploader Size */
            Sstat theStat;
            if (Stat(apploaderIn, &theStat))
                LogModule.report(logvisor::Fatal, _S("unable to stat %s"), apploaderIn);

            /* Compute boot table members and write */
            size_t fstOff = 0x2440 + ROUND_UP_32(theStat.st_size);
            size_t fstSz = sizeof(FSTNode) * m_buildNodes.size();
            fstSz += m_buildNameOff;
            fstSz = ROUND_UP_32(fstSz);

            if (fstOff + fstSz >= 0x1F0000)
                LogModule.report(logvisor::Fatal,
                                 "FST flows into user area (one or the other is too big)");

            cws->write(nullptr, 0x420 - sizeof(Header));
            uint32_t vals[4];
            vals[0] = SBig(uint32_t(m_dolOffset >> uint64_t(2)));
            vals[1] = SBig(uint32_t(fstOff >> uint64_t(2)));
            vals[2] = SBig(uint32_t(fstSz));
            vals[3] = SBig(uint32_t(fstSz));
            cws->write(vals, 16);

            /* Write Apploader */
            cws->write(nullptr, 0x2440 - 0x430);
            std::unique_ptr<IFileIO::IReadStream> rs = NewFileIO(apploaderIn)->beginReadStream();
            char buf[8192];
            size_t xferSz = 0;
            SystemString apploaderName(apploaderIn);
            ++m_parent.m_progressIdx;
            while (true)
            {
                size_t rdSz = rs->read(buf, 8192);
                if (!rdSz)
                    break;
                cws->write(buf, rdSz);
                xferSz += rdSz;
                if (0x2440 + xferSz >= 0x1F0000)
                    LogModule.report(logvisor::Fatal,
                                     "apploader flows into user area (one or the other is too big)");
                m_parent.m_progressCB(m_parent.m_progressIdx, apploaderName, xferSz);
            }

            size_t fstOffRel = fstOff - 0x2440;
            if (xferSz > fstOffRel)
                LogModule.report(logvisor::Fatal, "apploader unexpectedly flows into FST");
            for (size_t i=0 ; i<fstOffRel-xferSz ; ++i)
                cws->write("\xff", 1);

            /* Write FST */
            cws->write(m_buildNodes.data(), m_buildNodes.size() * sizeof(FSTNode));
            for (const std::string& str : m_buildNames)
                cws->write(str.data(), str.size()+1);
        }

        /* Write new crypto content size */
        uint64_t groupCount = m_curUser / 0x1F0000;
        uint64_t cryptContentSize = (groupCount * 0x200000) >> uint64_t(2);
        uint32_t cryptContentSizeBig = SBig(uint32_t(cryptContentSize));
        ws = m_parent.getFileIO().beginWriteStream(m_baseOffset + 0x2BC);
        ws->write(&cryptContentSizeBig, 0x4);

        /* Write new H3 */
        ws = m_parent.getFileIO().beginWriteStream(m_baseOffset + h3Off);
        ws->write(m_h3, 0x18000);

        /* Compute content hash and replace in TMD */
        sha1nfo sha;
        sha1_init(&sha);
        sha1_write(&sha, (char*)m_h3, 0x18000);
        memcpy(tmdData.get() + 0x1F4, sha1_result(&sha), 20);

        /* Same for content size */
        uint64_t contentSize = groupCount * 0x1F0000;
        uint64_t contentSizeBig = SBig(contentSize);
        memcpy(tmdData.get() + 0x1EC, &contentSizeBig, 8);

        /* Zero-out TMD signature to simplify brute-force */
        memset(tmdData.get() + 0x4, 0, 0x100);

        /* Brute-force zero-starting hash */
        size_t tmdCheckSz = tmdSz - 0x140;
        struct BFWindow
        {
            uint64_t word[7];
        }* bfWindow = (BFWindow*)(tmdData.get() + 0x19A);
        bool good = false;
        uint64_t attempts = 0;
        SystemString bfName(_S("Brute force attempts"));
        ++m_parent.m_progressIdx;
        for (int w=0 ; w<7 ; ++w)
        {
            for (uint64_t i=0 ; i<UINT64_MAX ; ++i)
            {
                bfWindow->word[w] = i;
                sha1_init(&sha);
                sha1_write(&sha, (char*)(tmdData.get() + 0x140), tmdCheckSz);
                uint8_t* hash = sha1_result(&sha);
                ++attempts;
                if (hash[0] == 0)
                {
                    good = true;
                    break;
                }
                m_parent.m_progressCB(m_parent.m_progressIdx, bfName, attempts);
            }
            if (good)
                break;
        }
        m_parent.m_progressCB(m_parent.m_progressIdx, bfName, attempts);

        ws = m_parent.getFileIO().beginWriteStream(m_baseOffset + 0x2C0);
        ws->write(tmdData.get(), tmdSz);

        return m_baseOffset + dataOff + groupCount * 0x200000;
    }