/* * Generate a cookie (aka SPI) * First argument is true if we're to create an Initiator cookie. * Length SHOULD be a multiple of sizeof(u_int32_t). * * As responder, we use a hashing method to get a pseudo random * value instead of using our own random pool. It will prevent * an attacker from gaining raw data from our random pool and * it will prevent an attacker from depleting our random pool * or entropy. */ void get_cookie(bool initiator, u_int8_t cookie[COOKIE_SIZE], const ip_address *addr) { do { if (initiator) { get_rnd_bytes(cookie, COOKIE_SIZE); } else { static u_int32_t counter = 0; /* STATIC */ unsigned char addr_buff[ sizeof(union { struct in_addr A; struct in6_addr B; })]; u_char buffer[SHA2_256_DIGEST_SIZE]; sha256_context ctx; size_t addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff)); sha256_init(&ctx); sha256_write(&ctx, addr_buff, addr_length); sha256_write(&ctx, secret_of_the_day, sizeof(secret_of_the_day)); counter++; sha256_write(&ctx, (const void *) &counter, sizeof(counter)); sha256_final(buffer, &ctx); /* cookie size is smaller than any hash output sizes */ memcpy(cookie, buffer, COOKIE_SIZE); } } while (is_zero_cookie(cookie)); /* probably never loops */ }
/* Update the message digest with the contents of INBUF with length INLEN. */ static void sha256_write (void *context, byte *inbuf, size_t inlen) { SHA256_CONTEXT *hd = context; if (hd->count == 64) { /* flush the buffer */ transform (hd, hd->buf); _gcry_burn_stack (74*4+32); hd->count = 0; hd->nblocks++; } if (!inbuf) return; if (hd->count) { for (; inlen && hd->count < 64; inlen--) hd->buf[hd->count++] = *inbuf++; sha256_write (hd, NULL, 0); if (!inlen) return; } while (inlen >= 64) { transform (hd, inbuf); hd->count = 0; hd->nblocks++; inlen -= 64; inbuf += 64; } _gcry_burn_stack (74*4+32); for (; inlen && hd->count < 64; inlen--) hd->buf[hd->count++] = *inbuf++; }
static void make_sha256(const void *buf, size_t bufLen, BYTE *tmpHash) { SHA256_CONTEXT tmp; sha256_init(&tmp); sha256_write(&tmp, buf, bufLen); sha256_final(&tmp, tmpHash); }
/* Update the message digest with the contents of INBUF with length INLEN. */ static void sha256_write(SHA256_CONTEXT *hd, const void *inbuf_arg, size_t inlen) { const unsigned char *inbuf = (const unsigned char *)inbuf_arg; 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++; sha256_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++; }
void SHA256_Test() { u8 i,k; u8 *hash; u8 hash1[32]; u8 output[65]; u32 t1, t2; UARTWriteLine("Start SHA256 Test..."); TimerInit(); t1 = GetTime(); for (k = 0; k < 100; k++) { sha256_init(); for (i = 0; i < 80; i++) sha256_write(test_vector[i]); hash = sha256_result(); memcpy(hash1, hash, 32); sha256_init(); for (i = 0; i < 32; i++) sha256_write(hash1[i]); hash = sha256_result(); memcpy(hash1, hash, 32); } t2 = GetTime(); for (i = 0; i < 32; i++) { sprintf(output + i * 2, "%02X", hash1[i]); } output[64] = '\0'; UARTWriteLine("SHA256 Result:"); UARTWriteString(output); sprintf(output, "%u", t2 - t1); UARTWriteLine("100 DHash(ms):"); UARTWriteString(output); }
void sha256_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, unsigned int ole) { sha256_context ctx; unsigned int length; if (ole < 1) return; memset(ob, 0, ole); if (ole > 32) ole = 32; sha256_init(&ctx); sha256_write(&ctx, ib, ile); SECStatus status = PK11_DigestFinal(ctx.ctx_nss, ob, &length, ole); PR_ASSERT(length == ole); PR_ASSERT(status == SECSuccess); PK11_DestroyContext(ctx.ctx_nss, PR_TRUE); DBG(DBG_CRYPT, DBG_log("NSS: sha256 final end")); }
/* * 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; }
/* The routine finally terminates the computation and returns the digest. The handle is prepared for a new cycle, but adding bytes to the handle will the destroy the returned buffer. Returns: 32 bytes with the message the digest. */ static void sha256_final(void *context) { SHA256_CONTEXT *hd = context; u32 t, msb, lsb; byte *p; sha256_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; sha256_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); _gcry_burn_stack (74*4+32); 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); X(5); X(6); X(7); #undef X }
static void sha256_write_thunk(union hash_ctx *ctx, const unsigned char *datap, size_t length) { sha256_write(&ctx->ctx_sha256, datap, length); }
int main(int argc, char *argv[]) { size_t i; unsigned int password_found; struct SRP_mitm_t mitm; struct server_t s; struct client_t c; mpz_t N, g, k, u, useless_u, x; mpz_t tmp_base, tmp_e, S; uint8_t buf[SHA256_HASH_SIZE]; struct sha256nfo ctx; char *c_salt_str, *s_salt_str, *email, *candidate_p; mpz_init_set_str(N, NIST_N, 16 ); mpz_init_set_str(g, NIST_g, 0 ); mpz_init_set_str(k, NIST_k, 0 ); // Init server server_init(&s, N, g, k, 1); server_add_entry(&s, "*****@*****.**", 16, "password123", 11); // Init client client_init(&c, N, g, k); // Init MITM server_init(&(mitm.s), N, g, k, 1); server_add_entry(&(mitm.s), "*****@*****.**", 16, "uselesspass", 11); client_init(&(mitm.c), N, g, k); /* * MITM client pubkey interception * * S <--A-- MITM <--A-- C * --u--> MITM --u--> C */ email = "*****@*****.**"; c_salt_str = mitm_server_init_shared(&(mitm.s), email, strlen(email), c.srp.pubkey, &u); s_salt_str = server_init_shared(&s, email, strlen(email), mitm.c.srp.pubkey, &useless_u); if (NULL != c_salt_str) { c.salt_str = malloc(strlen(c_salt_str)*sizeof(char)); if (NULL != c.salt_str) { /* * The MITM attacker does not know the client private DH key 'a'. * However sending B == g cirumvent this unknown, since : * S = B**(a + ux) % n <==> S = (g**a).(g**ux) %n * <==> S = A.g**ux %n */ c.salt_len = strlen(c_salt_str); memcpy(c.salt_str, c_salt_str, strlen(c_salt_str)); client_init_shared(&c, "password123", strlen("password123") , mitm.s.srp.pubkey , u); /* * MITM offline dictionnary attack */ i = 0x00; password_found = 0x00; candidate_p = weak_passwords[0]; while (NULL != candidate_p && !password_found) { srp_utils_gen_x(&x, candidate_p, strlen(candidate_p),c_salt_str, strlen(c_salt_str)); // g**(u.x) mpz_init(tmp_base); mpz_init_set(tmp_e, u); mpz_mul(tmp_e, tmp_e, x ); mpz_powm(tmp_base, g, tmp_e, N); mpz_init(S); mpz_mul(S, mitm.c.srp.pubkey, tmp_base ); mpz_mod(S, S, N); srp_utils_gen_shared_key(mitm.c.K, S); mpz_clear(tmp_base); mpz_clear(tmp_e); mpz_clear(S); mpz_clear(x); if (!memcmp(mitm.c.K, c.K, sizeof(c.K))) { printf("Password successfully infered : %s !\n", candidate_p); password_found = 0x01; } else { i++; candidate_p = weak_passwords[i]; } } /* * Final server validation */ if (password_found) { mitm.c.salt_len = strlen(s_salt_str); mitm.c.salt_str = malloc(strlen(s_salt_str)*sizeof(char)); if (NULL == mitm.c.salt_str) return 0x01; memcpy(mitm.c.salt_str, s_salt_str, strlen(s_salt_str)); client_init_shared(&(mitm.c), candidate_p, strlen(candidate_p) , s.srp.pubkey, useless_u); sha256_init_Hmac(&ctx, mitm.c.K, SHA256_HASH_SIZE); sha256_write(&ctx, (uint8_t*) mitm.c.salt_str, mitm.c.salt_len); sha256_result_Hmac(&ctx, buf); if (server_check_password(&s, email, strlen(email), buf)) printf("We have a valid user : %s !\n", email); else printf("The following user is not registered : %s !\n", email); } else printf("The following user is not registered : %s !\n", email); } } else printf("The following user is not registered : %s !\n", email); client_cleanup(&c); server_cleanup(&s); server_cleanup(&(mitm.s)); client_cleanup(&(mitm.c)); mpz_clear(N); mpz_clear(g); mpz_clear(k); return 0x00; }
static void sha256_final(SHA256_CONTEXT *hd) { u32 t, msb, lsb; byte *p; sha256_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; sha256_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 ); burn_stack (328); 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); X(5); X(6); /* Note that this last chunk is included even for SHA224. We just ignore it. */ X(7); #undef X }