/* initialise the credentials state for ADS-style 128 bit session keys this call is made after the netr_ServerReqChallenge call */ static void creds_init_128bit(struct creds_CredentialState *creds, const struct netr_Credential *client_challenge, const struct netr_Credential *server_challenge, const struct samr_Password *machine_password) { unsigned char zero[4], tmp[16]; HMACMD5Context ctx; struct MD5Context md5; ZERO_STRUCT(creds->session_key); memset(zero, 0, sizeof(zero)); hmac_md5_init_rfc2104(machine_password->hash, sizeof(machine_password->hash), &ctx); MD5Init(&md5); MD5Update(&md5, zero, sizeof(zero)); MD5Update(&md5, client_challenge->data, 8); MD5Update(&md5, server_challenge->data, 8); MD5Final(tmp, &md5); hmac_md5_update(tmp, sizeof(tmp), &ctx); hmac_md5_final(creds->session_key, &ctx); creds->client = *client_challenge; creds->server = *server_challenge; des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1); des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1); creds->seed = creds->client; }
/*********************************************************************** the microsoft version of hmac_md5 initialisation. ***********************************************************************/ _PUBLIC_ void hmac_md5_init_limK_to_64(const uint8_t *key, int key_len, HMACMD5Context *ctx) { /* if key is longer than 64 bytes truncate it */ if (key_len > 64) { key_len = 64; } hmac_md5_init_rfc2104(key, key_len, ctx); }
static void creds_init_128(struct dcinfo *dc, const DOM_CHAL *clnt_chal_in, const DOM_CHAL *srv_chal_in, const unsigned char mach_pw[16]) { unsigned char zero[4], tmp[16]; HMACMD5Context ctx; struct MD5Context md5; /* Just in case this isn't already there */ memcpy(dc->mach_pw, mach_pw, 16); ZERO_STRUCT(dc->sess_key); memset(zero, 0, sizeof(zero)); hmac_md5_init_rfc2104(mach_pw, 16, &ctx); MD5Init(&md5); MD5Update(&md5, zero, sizeof(zero)); MD5Update(&md5, clnt_chal_in->data, 8); MD5Update(&md5, srv_chal_in->data, 8); MD5Final(tmp, &md5); hmac_md5_update(tmp, sizeof(tmp), &ctx); hmac_md5_final(dc->sess_key, &ctx); /* debug output */ DEBUG(5,("creds_init_128\n")); DEBUG(5,("\tclnt_chal_in: %s\n", credstr(clnt_chal_in->data))); DEBUG(5,("\tsrv_chal_in : %s\n", credstr(srv_chal_in->data))); dump_data_pw("\tsession_key ", (const unsigned char *)dc->sess_key, 16); /* Generate the next client and server creds. */ des_crypt112(dc->clnt_chal.data, /* output */ clnt_chal_in->data, /* input */ dc->sess_key, /* input */ 1); des_crypt112(dc->srv_chal.data, /* output */ srv_chal_in->data, /* input */ dc->sess_key, /* input */ 1); /* Seed is the client chal. */ memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8); }
/* This uses the test values from rfc 2104, 2202 */ bool torture_local_crypto_hmacmd5(struct torture_context *torture) { bool ret = true; uint32_t i; struct { DATA_BLOB key; DATA_BLOB data; DATA_BLOB md5; } testarray[8]; TALLOC_CTX *tctx = talloc_new(torture); if (!tctx) { return false; }; testarray[0].key = data_blob_repeat_byte(0x0b, 16); testarray[0].data = data_blob_string_const("Hi There"); testarray[0].md5 = strhex_to_data_blob(tctx, "9294727a3638bb1c13f48ef8158bfc9d"); testarray[1].key = data_blob_string_const("Jefe"); testarray[1].data = data_blob_string_const("what do ya want for nothing?"); testarray[1].md5 = strhex_to_data_blob(tctx, "750c783e6ab0b503eaa86e310a5db738"); testarray[2].key = data_blob_repeat_byte(0xaa, 16); testarray[2].data = data_blob_repeat_byte(0xdd, 50); testarray[2].md5 = strhex_to_data_blob(tctx, "56be34521d144c88dbb8c733f0e8b3f6"); testarray[3].key = strhex_to_data_blob(tctx, "0102030405060708090a0b0c0d0e0f10111213141516171819"); testarray[3].data = data_blob_repeat_byte(0xcd, 50); testarray[3].md5 = strhex_to_data_blob(tctx, "697eaf0aca3a3aea3a75164746ffaa79"); testarray[4].key = data_blob_repeat_byte(0x0c, 16); testarray[4].data = data_blob_string_const("Test With Truncation"); testarray[4].md5 = strhex_to_data_blob(tctx, "56461ef2342edc00f9bab995690efd4c"); testarray[5].key = data_blob_repeat_byte(0xaa, 80); testarray[5].data = data_blob_string_const("Test Using Larger Than Block-Size Key - Hash Key First"); testarray[5].md5 = strhex_to_data_blob(tctx, "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"); testarray[6].key = data_blob_repeat_byte(0xaa, 80); testarray[6].data = data_blob_string_const("Test Using Larger Than Block-Size Key " "and Larger Than One Block-Size Data"); testarray[6].md5 = strhex_to_data_blob(tctx, "6f630fad67cda0ee1fb1f562db3aa53e"); testarray[7].key = data_blob(NULL, 0); for (i=0; testarray[i].key.data; i++) { HMACMD5Context ctx; uint8_t md5[16]; int e; hmac_md5_init_rfc2104(testarray[i].key.data, testarray[i].key.length, &ctx); hmac_md5_update(testarray[i].data.data, testarray[i].data.length, &ctx); hmac_md5_final(md5, &ctx); e = memcmp(testarray[i].md5.data, md5, MIN(testarray[i].md5.length, sizeof(md5))); if (e != 0) { printf("hmacmd5 test[%u]: failed\n", i); dump_data(0, testarray[i].key.data, testarray[i].key.length); dump_data(0, testarray[i].data.data, testarray[i].data.length); dump_data(0, testarray[i].md5.data, testarray[i].md5.length); dump_data(0, md5, sizeof(md5)); ret = false; } } talloc_free(tctx); return ret; }