static bool verify_credentials(struct cram_auth_request *request, const unsigned char *credentials, size_t size) { unsigned char digest[MD5_RESULTLEN]; struct hmac_context ctx; const char *response_hex; if (size != CRAM_MD5_CONTEXTLEN) { auth_request_log_error(&request->auth_request, "cram-md5", "invalid credentials length"); return FALSE; } hmac_init(&ctx, NULL, 0, &hash_method_md5); hmac_md5_set_cram_context(&ctx, credentials); hmac_update(&ctx, request->challenge, strlen(request->challenge)); hmac_final(&ctx, digest); response_hex = binary_to_hex(digest, sizeof(digest)); if (memcmp(response_hex, request->response, sizeof(digest)*2) != 0) { auth_request_log_info(&request->auth_request, "cram-md5", "password mismatch"); return FALSE; } return TRUE; }
/** * @internal * * @brief Verify the hmac of a packet * * @param session The session to use. * @param buffer The buffer to verify the hmac from. * @param mac The mac to compare with the hmac. * * @return 0 if hmac and mac are equal, < 0 if not or an error * occurred. */ int packet_hmac_verify(ssh_session session, ssh_buffer buffer, unsigned char *mac, enum ssh_hmac_e type) { unsigned char hmacbuf[DIGEST_MAX_LEN] = {0}; HMACCTX ctx; unsigned int len; uint32_t seq; ctx = hmac_init(session->current_crypto->decryptMAC, hmac_digest_len(type), type); if (ctx == NULL) { return -1; } seq = htonl(session->recv_seq); hmac_update(ctx, (unsigned char *) &seq, sizeof(uint32_t)); hmac_update(ctx, buffer_get_rest(buffer), buffer_get_rest_len(buffer)); hmac_final(ctx, hmacbuf, &len); #ifdef DEBUG_CRYPTO ssh_print_hexa("received mac",mac,len); ssh_print_hexa("Computed mac",hmacbuf,len); ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t)); #endif if (memcmp(mac, hmacbuf, len) == 0) { return 0; } return -1; }
unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) { struct ssh_cipher_struct *crypto = NULL; HMACCTX ctx = NULL; char *out = NULL; unsigned int finallen; uint32_t seq; if (!session->current_crypto) { return NULL; /* nothing to do here */ } if(len % session->current_crypto->in_cipher->blocksize != 0){ ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len); return NULL; } out = malloc(len); if (out == NULL) { return NULL; } seq = ntohl(session->send_seq); crypto = session->current_crypto->out_cipher; if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey, session->current_crypto->encryptIV) < 0) { SAFE_FREE(out); return NULL; } if (session->version == 2) { ctx = hmac_init(session->current_crypto->encryptMAC,20,SSH_HMAC_SHA1); if (ctx == NULL) { SAFE_FREE(out); return NULL; } hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t)); hmac_update(ctx,data,len); hmac_final(ctx,session->current_crypto->hmacbuf,&finallen); #ifdef DEBUG_CRYPTO ssh_print_hexa("mac: ",data,len); if (finallen != 20) { printf("Final len is %d\n",finallen); } ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, 20); #endif } crypto->cbc_encrypt(crypto, data, out, len); memcpy(data, out, len); memset(out, 0, len); SAFE_FREE(out); if (session->version == 2) { return session->current_crypto->hmacbuf; } return NULL; }
unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len) { struct ssh_cipher_struct *crypto = NULL; HMACCTX ctx = NULL; char *out = NULL; unsigned int finallen; uint32_t seq; enum ssh_hmac_e type; assert(len); if (!session->current_crypto) { return NULL; /* nothing to do here */ } if((len - session->current_crypto->out_cipher->lenfield_blocksize) % session->current_crypto->out_cipher->blocksize != 0){ ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len); return NULL; } out = malloc(len); if (out == NULL) { return NULL; } type = session->current_crypto->out_hmac; seq = ntohl(session->send_seq); crypto = session->current_crypto->out_cipher; if (crypto->aead_encrypt != NULL) { crypto->aead_encrypt(crypto, data, out, len, session->current_crypto->hmacbuf, session->send_seq); } else { ctx = hmac_init(session->current_crypto->encryptMAC, hmac_digest_len(type), type); if (ctx == NULL) { SAFE_FREE(out); return NULL; } hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t)); hmac_update(ctx,data,len); hmac_final(ctx,session->current_crypto->hmacbuf,&finallen); #ifdef DEBUG_CRYPTO ssh_print_hexa("mac: ",data,hmac_digest_len(type)); if (finallen != hmac_digest_len(type)) { printf("Final len is %d\n",finallen); } ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, hmac_digest_len(type)); #endif crypto->encrypt(crypto, data, out, len); } memcpy(data, out, len); explicit_bzero(out, len); SAFE_FREE(out); return session->current_crypto->hmacbuf; }
void fs_hmac_generic(const unsigned char *data, int size, const unsigned char *extra, int extra_size, unsigned char *hmac) { int i; hmac_ctx ctx; hmac_init(&ctx,hmac_key,0x14); hmac_update(&ctx,extra,extra_size); hmac_update(&ctx,data,size); hmac_final(&ctx,hmac); }
static int pkcs5_pbkdf2(const struct hash_method *hash, const unsigned char *password, size_t password_len, const unsigned char *salt, size_t salt_len, unsigned int iter, uint32_t length, buffer_t *result) { if (length < 1 || iter < 1) return -1; size_t l = (length + hash->digest_size - 1)/hash->digest_size; /* same as ceil(length/hash->digest_size) */ unsigned char dk[l * hash->digest_size]; unsigned char *block; struct hmac_context hctx; unsigned int c,i,t; unsigned char U_c[hash->digest_size]; for(t = 0; t < l; t++) { block = &(dk[t*hash->digest_size]); /* U_1 = PRF(Password, Salt|| INT_BE32(Block_Number)) */ c = htonl(t+1); hmac_init(&hctx, password, password_len, hash); hmac_update(&hctx, salt, salt_len); hmac_update(&hctx, &c, sizeof(c)); hmac_final(&hctx, U_c); /* block = U_1 ^ .. ^ U_iter */ memcpy(block, U_c, hash->digest_size); /* U_c = PRF(Password, U_c-1) */ for(c = 1; c < iter; c++) { hmac_init(&hctx, password, password_len, hash); hmac_update(&hctx, U_c, hash->digest_size); hmac_final(&hctx, U_c); for(i = 0; i < hash->digest_size; i++) block[i] ^= U_c[i]; } } buffer_append(result, dk, length); return 0; }
void do_hmac_test ( HmacState_t h, uint32_t testnum, const uint8_t *data, size_t datalen, const uint8_t *expected, size_t expectedlen) { uint8_t digest[32]; (void) hmac_init (h); (void) hmac_update (h, data, datalen); (void) hmac_final (digest, SHA256_DIGEST_SIZE, h); check_result(testnum, expected, expectedlen, digest, sizeof(digest), 1); }
size_t hmac_sha(const hash_t *key, const hash_t *msg, hash_t *hash, const evp_md_t *md) { size_t len; hash_t buff[MAX_LEN]; hmac_ctx_t ctx; hmac_ctx_init(&ctx); hmac_init(&ctx, key, strlen((char *)key), md); hmac_update(&ctx, msg, strlen((char *)msg)); hmac_final(&ctx, buff, (unsigned int *)&len); hmac_ctx_cleanup(&ctx); memcpy(hash, buff, len); return len; }
int packet_hmac_verify(SSH_SESSION *session,BUFFER *buffer,unsigned char *mac){ HMACCTX ctx; unsigned char hmacbuf[EVP_MAX_MD_SIZE]; unsigned int len; u32 seq=htonl(session->recv_seq); ctx=hmac_init(session->current_crypto->decryptMAC,20,HMAC_SHA1); hmac_update(ctx,(unsigned char *)&seq,sizeof(u32)); hmac_update(ctx,buffer_get(buffer),buffer_get_len(buffer)); hmac_final(ctx,hmacbuf,&len); #ifdef DEBUG_CRYPTO ssh_print_hexa("received mac",mac,len); ssh_print_hexa("Computed mac",hmacbuf,len); ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(u32)); #endif return memcmp(mac,hmacbuf,len); }
/** * Calculate HMAC-SHA1 MIC for EAPOL-Key frame * * @v kck Key Confirmation Key, 16 bytes * @v msg Message to calculate MIC over * @v len Number of bytes to calculate MIC over * @ret mic Calculated MIC, 16 bytes long */ static void ccmp_kie_mic ( const void *kck, const void *msg, size_t len, void *mic ) { u8 sha1_ctx[SHA1_CTX_SIZE]; u8 kckb[16]; u8 hash[SHA1_SIZE]; size_t kck_len = 16; memcpy ( kckb, kck, kck_len ); hmac_init ( &sha1_algorithm, sha1_ctx, kckb, &kck_len ); hmac_update ( &sha1_algorithm, sha1_ctx, msg, len ); hmac_final ( &sha1_algorithm, sha1_ctx, kckb, &kck_len, hash ); memcpy ( mic, hash, 16 ); }
const char *auth_token_get(const char *service, const char *session_pid, const char *username, const char *session_id) { struct hmac_context ctx; unsigned char result[SHA1_RESULTLEN]; hmac_init(&ctx, (const unsigned char*)username, strlen(username), &hash_method_sha1); hmac_update(&ctx, session_pid, strlen(session_pid)); if (session_id != NULL && *session_id != '\0') hmac_update(&ctx, session_id, strlen(session_id)); hmac_update(&ctx, service, strlen(service)); hmac_update(&ctx, auth_token_secret, sizeof(auth_token_secret)); hmac_final(&ctx, result); return binary_to_hex(result, sizeof(result)); }
buffer_t *t_hmac_data(const struct hash_method *meth, const unsigned char *key, size_t key_len, const void *data, size_t data_len) { struct hmac_context ctx; i_assert(meth != NULL); i_assert(key != NULL && key_len > 0); i_assert(data != NULL || data_len == 0); buffer_t *res = buffer_create_dynamic(pool_datastack_create(), meth->digest_size); hmac_init(&ctx, key, key_len, meth); if (data_len > 0) hmac_update(&ctx, data, data_len); unsigned char *buf = buffer_get_space_unsafe(res, 0, meth->digest_size); hmac_final(&ctx, buf); return res; }
static const unsigned char * imap_urlauth_internal_generate(const char *rumpurl, const unsigned char mailbox_key[IMAP_URLAUTH_KEY_LEN], size_t *token_len_r) { struct hmac_context hmac; unsigned char *token; token = t_new(unsigned char, SHA1_RESULTLEN + 1); token[0] = IMAP_URLAUTH_MECH_INTERNAL_VERSION; hmac_init(&hmac, mailbox_key, IMAP_URLAUTH_KEY_LEN, &hash_method_sha1); hmac_update(&hmac, rumpurl, strlen(rumpurl)); hmac_final(&hmac, token+1); *token_len_r = SHA1_RESULTLEN + 1; return token; }
/** * Update the HMAC_DRBG value * * @v hash Underlying hash algorithm * @v state HMAC_DRBG internal state * @v data Provided data * @v len Length of provided data * @v single Single byte used in concatenation * * This function carries out the operation * * V = HMAC ( K, V ) * * as used by hmac_drbg_update() and hmac_drbg_generate() */ static void hmac_drbg_update_value ( struct digest_algorithm *hash, struct hmac_drbg_state *state ) { uint8_t context[ hash->ctxsize ]; size_t out_len = hash->digestsize; /* Sanity checks */ assert ( hash != NULL ); assert ( state != NULL ); /* V = HMAC ( K, V ) */ hmac_init ( hash, context, state->key, &out_len ); assert ( out_len == hash->digestsize ); hmac_update ( hash, context, state->value, out_len ); hmac_final ( hash, context, state->key, &out_len, state->value ); assert ( out_len == hash->digestsize ); DBGC ( state, "HMAC_DRBG_%s %p V = HMAC ( K, V ) :\n", hash->name, state ); DBGC_HDA ( state, 0, state->value, out_len ); }
unsigned char * packet_encrypt(SSH_SESSION *session,void *data,u32 len){ struct crypto_struct *crypto; HMACCTX ctx; char *out; unsigned int finallen; u32 seq=ntohl(session->send_seq); if(!session->current_crypto) return NULL; /* nothing to do here */ crypto= session->current_crypto->out_cipher; ssh_log(session,SSH_LOG_PACKET,"encrypting packet with seq num: %d, len: %d",session->send_seq,len); #ifdef HAVE_LIBGCRYPT crypto->set_encrypt_key(crypto,session->current_crypto->encryptkey,session->current_crypto->encryptIV); #elif defined HAVE_LIBCRYPTO crypto->set_encrypt_key(crypto,session->current_crypto->encryptkey); #endif out=malloc(len); if(session->version==2){ ctx=hmac_init(session->current_crypto->encryptMAC,20,HMAC_SHA1); hmac_update(ctx,(unsigned char *)&seq,sizeof(u32)); hmac_update(ctx,data,len); hmac_final(ctx,session->current_crypto->hmacbuf,&finallen); #ifdef DEBUG_CRYPTO ssh_print_hexa("mac :",data,len); if(finallen!=20) printf("Final len is %d\n",finallen); ssh_print_hexa("packet hmac",session->current_crypto->hmacbuf,20); #endif } #ifdef HAVE_LIBGCRYPT crypto->cbc_encrypt(crypto,data,out,len); #elif defined HAVE_LIBCRYPTO crypto->cbc_encrypt(crypto,data,out,len,session->current_crypto->encryptIV); #endif memcpy(data,out,len); memset(out,0,len); free(out); if(session->version==2) return session->current_crypto->hmacbuf; else return NULL; }
int compute_context_digest(TPM_CONTEXT_BLOB *contextBlob, TPM_DIGEST *digest) { BYTE *buf, *ptr; UINT32 len; hmac_ctx_t hmac_ctx; len = sizeof_TPM_CONTEXT_BLOB((*contextBlob)); buf = ptr = tpm_malloc(len); if (buf == NULL) return -1; if (tpm_marshal_TPM_CONTEXT_BLOB(&ptr, &len, contextBlob)) { tpm_free(buf); return -1; } memset(&buf[30], 0, 20); hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(tpmData.permanent.data.tpmProof.nonce)); hmac_update(&hmac_ctx, buf, sizeof_TPM_CONTEXT_BLOB((*contextBlob))); hmac_final(&hmac_ctx, digest->digest); tpm_free(buf); return 0; }
/** * @internal * * @brief Verify the hmac of a packet * * @param session The session to use. * @param buffer The buffer to verify the hmac from. * @param mac The mac to compare with the hmac. * * @return 0 if hmac and mac are equal, < 0 if not or an error * occurred. */ int ssh_packet_hmac_verify(ssh_session session, ssh_buffer buffer, uint8_t *mac, enum ssh_hmac_e type) { unsigned char hmacbuf[DIGEST_MAX_LEN] = {0}; HMACCTX ctx; unsigned int len; uint32_t seq; /* AEAD type have no mac checking */ if (type == SSH_HMAC_AEAD_POLY1305) { return SSH_OK; } ctx = hmac_init(session->current_crypto->decryptMAC, hmac_digest_len(type), type); if (ctx == NULL) { return -1; } seq = htonl(session->recv_seq); hmac_update(ctx, (unsigned char *) &seq, sizeof(uint32_t)); hmac_update(ctx, ssh_buffer_get(buffer), ssh_buffer_get_len(buffer)); hmac_final(ctx, hmacbuf, &len); #ifdef DEBUG_CRYPTO ssh_print_hexa("received mac",mac,len); ssh_print_hexa("Computed mac",hmacbuf,len); ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t)); #endif if (secure_memcmp(mac, hmacbuf, len) == 0) { return 0; } return -1; }
int32_t hmac_prng_generate ( uint8_t *out, /* IN/OUT -- buffer to receive output */ uint32_t outlen, /* IN -- size of out buffer in bytes */ HmacPrng_t prng) { /* IN/OUT -- the PRNG state */ uint32_t bufferlen; /* input sanity check: */ if (out == (uint8_t *) 0 || prng == (HmacPrng_t) 0 || outlen == 0 || outlen > MAX_OUT) { return 0; } else if (prng->countdown == 0) { return -1; } prng->countdown--; while (outlen != 0) { /* operate HMAC in OFB mode to create "random" outputs */ (void) hmac_init (&prng->h); (void) hmac_update (&prng->h, prng->v, sizeof (prng->v)); (void) hmac_final (prng->v, sizeof(prng->v), &prng->h); bufferlen = (SHA256_DIGEST_SIZE > outlen) ? outlen : SHA256_DIGEST_SIZE; (void) copy (out, bufferlen, prng->v, bufferlen); out += bufferlen; outlen = (outlen > SHA256_DIGEST_SIZE) ? (outlen - SHA256_DIGEST_SIZE) : 0; } /* block future PRNG compromises from revealing past state */ update (prng, prng->v, SHA256_DIGEST_SIZE); return 1; }
int main() { unsigned char ordinal[4] = { 0x00, 0x00, 0x00, 0x17 }; HMAC_CTX hmac; unsigned char shared_secret[20] = { 0x42, 0xAC ,0xAF, 0xF1, 0xD4 ,0x99, 0x3C, 0xCA, 0xC9, 0x00, 0x3C, 0xCA, 0xC8, 0x00, 0x3C, 0xCA, 0xC8, 0x00, 0x3C, 0xCA }; unsigned char hashDigest[20] = { 0x6F, 0x02, 0x98, 0x86, 0x25, 0x8C, 0xAF, 0x9F, 0xC2, 0x4A, 0x70, 0x6B, 0xBD, 0x44, 0xBC, 0x5E, 0x57, 0xD8, 0x32, 0xA1 }; unsigned char even[20] = { 0x76, 0xF4, 0x26, 0x85, 0xF4, 0x8E, 0x33, 0x3B, 0x9B, 0x8B, 0xBA, 0xCF, 0x8D, 0x12, 0x42, 0x39, 0x7F, 0x8A, 0xC3, 0x23 }; unsigned char odd[20] = { 0xFE, 0x26, 0x68, 0x4C, 0x27, 0xB6, 0x50, 0x2A, 0xEC, 0x90, 0x85, 0xAA, 0xD9, 0x80, 0x38, 0x13, 0x9C, 0xD6, 0xE5, 0xBF }; //unsigned char h[20] = { 0x6B, 0xB0, 0x85, 0x4C, 0xA0, 0x9C, 0xAF, 0x9C, 0x3C, 0xCC, 0xA5, 0x57, 0x30, 0x85, 0xB9, 0x5F, 0x7B, 0x85, 0xE9, 0xCB }; unsigned char new_h[20] = { 0x00 }; unsigned char new_h2[20] = { 0x00 }; unsigned char xor_key[20] = { 0x00 }; unsigned char encrypted_secret[20] = { 0x00 }; unsigned char secret_key[20] = { 0x00 }; unsigned char shared[20] = { 0x00 }; unsigned char cont = 0x00; unsigned char osapEven[20] = { 0x03 ,0xF0 ,0x02 ,0xB6, 0xA9 ,0x2C ,0x48 ,0xAE, 0x3E ,0x0E ,0xEA ,0xA1, 0x47 ,0x5C ,0x3D ,0x21, 0xE8 ,0x06 ,0x38 ,0xD6 }; unsigned char osapOdd[20] = { 0x67, 0x04, 0x00, 0x4E, 0x36, 0x0C, 0x6E, 0x4A, 0xCB, 0xDB, 0xBB, 0xE6, 0xDD, 0xE2, 0xF1, 0x46, 0x2C, 0xF0, 0x77, 0x01 }; hmac_init(secret_key, 20); hmac_update(osapEven, 20); hmac_update(osapOdd, 20); hmac_final(shared); int i; printf("ENC AUTH:\n"); for(i=0;i<20;i++) printf("%02X ", shared[i]); printf("\n"); unsigned char pcrInfoSize[4] = { 0x00, 0x00, 0x00, 0x2C }; unsigned char pcrInfo[44] = { 0x00 }; unsigned char data[20] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x54, 0x68, 0x69, 0x73, 0x49, 0x73, 0x4d, 0x65, 0x0A }; unsigned char data_len[4] = { 0x00, 0x00, 0x00, 0x14 }; pcrInfo[1] = 0x02; pcrInfo[2] = 0x00; unsigned int hmac_len = 20; hash_init(); hash_update(even, 20); hash_update(shared_secret, 20); hash_final(xor_key); for(i=0;i<20;i++) encrypted_secret[i] = xor_key[i] ^ secret_key[i]; printf("ENC AUTH:\n"); for(i=0;i<20;i++) printf("%02X ", encrypted_secret[i]); printf("\n"); hash_init(); hash_update(ordinal, 4); hash_update(encrypted_secret, 20); hash_update(pcrInfoSize, 4); hash_update(pcrInfo, 44); hash_update(data_len, 4); hash_update(data, 20); hash_final(hashDigest); printf("HASH DIGEST:\n"); for(i=0;i<20;i++) printf("%02X ", hashDigest[i]); printf("\n"); HMAC_CTX_init(&hmac); HMAC_Init(&hmac, shared_secret, 20, EVP_sha1()); HMAC_Update(&hmac, hashDigest, 20); HMAC_Update(&hmac, even, 20); HMAC_Update(&hmac, odd, 20); HMAC_Update(&hmac, &cont, 1); HMAC_Final(&hmac, new_h, &hmac_len); printf("OPENSSL HMAC:\n"); for(i=0;i<20;i++) printf("%02X ", new_h[i]); printf("\n"); h_init(shared_secret, 20); h_update(hashDigest, 20); h_update(even, 20); h_update(odd, 20); h_update(&cont, 1); h_final(new_h2); printf("IAIK HMAC:\n"); i=0; for(;i<20;i++) printf("%02X ", new_h2[i]); printf("\n"); return 0; }
/** * @brief Check if a hostname matches a openssh-style hashed known host. * * @param[in] host The host to check. * * @param[in] hashed The hashed value. * * @returns 1 if it matches, 0 otherwise. */ static int match_hashed_host(ssh_session session, const char *host, const char *sourcehash) { /* Openssh hash structure : * |1|base64 encoded salt|base64 encoded hash * hash is produced that way : * hash := HMAC_SHA1(key=salt,data=host) */ unsigned char buffer[256] = {0}; ssh_buffer salt; ssh_buffer hash; HMACCTX mac; char *source; char *b64hash; int match; unsigned int size; enter_function(); if (strncmp(sourcehash, "|1|", 3) != 0) { leave_function(); return 0; } source = strdup(sourcehash + 3); if (source == NULL) { leave_function(); return 0; } b64hash = strchr(source, '|'); if (b64hash == NULL) { /* Invalid hash */ SAFE_FREE(source); leave_function(); return 0; } *b64hash = '\0'; b64hash++; salt = base64_to_bin(source); if (salt == NULL) { SAFE_FREE(source); leave_function(); return 0; } hash = base64_to_bin(b64hash); SAFE_FREE(source); if (hash == NULL) { ssh_buffer_free(salt); leave_function(); return 0; } mac = hmac_init(buffer_get_rest(salt), buffer_get_rest_len(salt), HMAC_SHA1); if (mac == NULL) { ssh_buffer_free(salt); ssh_buffer_free(hash); leave_function(); return 0; } size = sizeof(buffer); hmac_update(mac, host, strlen(host)); hmac_final(mac, buffer, &size); if (size == buffer_get_rest_len(hash) && memcmp(buffer, buffer_get_rest(hash), size) == 0) { match = 1; } else { match = 0; } ssh_buffer_free(salt); ssh_buffer_free(hash); ssh_log(session, SSH_LOG_PACKET, "Matching a hashed host: %s match=%d", host, match); leave_function(); return match; }