/** LTC_HMAC a block of memory to produce the authentication tag @param hash The index of the hash to use @param key The secret key @param keylen The length of the secret key (octets) @param in The data to LTC_HMAC @param inlen The length of the data to LTC_HMAC (octets) @param out [out] Destination of the authentication tag @param outlen [in/out] Max size and resulting size of authentication tag @return CRYPT_OK if successful */ int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { hmac_state *hmac; int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* make sure hash descriptor is valid */ if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } /* is there a descriptor? */ if (hash_descriptor[hash].hmac_block != NULL) { return hash_descriptor[hash].hmac_block(key, keylen, in, inlen, out, outlen); } /* nope, so call the hmac functions */ /* allocate ram for hmac state */ hmac = (hmac_state*) XMALLOC(sizeof(hmac_state)); if (hmac == NULL) { return CRYPT_MEM; } if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(hmac, sizeof(hmac_state)); #endif XFREE(hmac); return err; }
/** LTC_HMAC a file @param hash The index of the hash you wish to use @param fname The name of the file you wish to LTC_HMAC @param key The secret key @param keylen The length of the secret key @param out [out] The LTC_HMAC authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled */ int hmac_file(const struct ltc_hash_descriptor *hash, const char *fname, const unsigned char *key, unsigned long keylen,unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE return CRYPT_NOP; #else hmac_state hmac; FILE *in; unsigned char buf[512]; size_t x; int err; LTC_ARGCHK(fname != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { return err; } in = fopen(fname, "rb"); if (in == NULL) { return CRYPT_FILE_NOTFOUND; } /* process the file contents */ do { x = fread(buf, 1, sizeof(buf), in); if ((err = hmac_process(&hmac, hash, buf, (unsigned long)x)) != CRYPT_OK) { /* we don't trap this error since we're already returning an error! */ fclose(in); return err; } } while (x == sizeof(buf)); if (fclose(in) != 0) { return CRYPT_ERROR; } /* get final hmac */ if ((err = hmac_done(&hmac, hash, out, outlen)) != CRYPT_OK) { return err; } #ifdef LTC_CLEAN_STACK /* clear memory */ zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; #endif }
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 ); }
/* Checks the mac in hashbuf, for the data in readbuf. * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ static int checkmac(buffer* macbuf, buffer* sourcebuf) { unsigned char macsize; hmac_state hmac; unsigned char tempbuf[MAX_MAC_LEN]; unsigned long hashsize; int len; macsize = ses.keys->recv_algo_mac->hashsize; if (macsize == 0) { return DROPBEAR_SUCCESS; } /* calculate the mac */ if (hmac_init(&hmac, find_hash(ses.keys->recv_algo_mac->hashdesc->name), ses.keys->recvmackey, ses.keys->recv_algo_mac->keysize) != CRYPT_OK) { dropbear_exit("HMAC error"); } /* sequence number */ STORE32H(ses.recvseq, tempbuf); if (hmac_process(&hmac, tempbuf, 4) != CRYPT_OK) { dropbear_exit("HMAC error"); } buf_setpos(sourcebuf, 0); len = sourcebuf->len; if (hmac_process(&hmac, buf_getptr(sourcebuf, len), len) != CRYPT_OK) { dropbear_exit("HMAC error"); } hashsize = sizeof(tempbuf); if (hmac_done(&hmac, tempbuf, &hashsize) != CRYPT_OK) { dropbear_exit("HMAC error"); } /* compare the hash */ if (memcmp(tempbuf, buf_getptr(macbuf, macsize), macsize) != 0) { return DROPBEAR_FAILURE; } else { return DROPBEAR_SUCCESS; } }
void ipkdb_init() { ipkdb_if.connect = IPKDB_DEF; ipkdbinit(); if ( ipkdbifinit(&ipkdb_if, 0) < 0 || !(ipkdb_if.flags&IPKDB_MYHW)) { /* Interface not found, drop IPKDB */ printf("IPKDB: No interface found!\n"); ipkdb_if.connect = IPKDB_NOIF; boothowto &= ~RB_KDB; } #ifdef IPKDBKEY if (!hmac_init()) ipkdb_if.connect = IPKDB_NO; #endif }
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; }
/* Create the packet mac, and append H(seqno|clearbuf) to the output */ static void writemac(buffer * outputbuffer, buffer * clearwritebuf) { int macsize; unsigned char seqbuf[4]; unsigned long hashsize; hmac_state hmac; TRACE(("enter writemac")); macsize = ses.keys->trans_algo_mac->hashsize; if (macsize > 0) { /* calculate the mac */ if (hmac_init(&hmac, find_hash(ses.keys->trans_algo_mac->hashdesc->name), ses.keys->transmackey, ses.keys->trans_algo_mac->keysize) != CRYPT_OK) { dropbear_exit("HMAC error"); } /* sequence number */ STORE32H(ses.transseq, seqbuf); if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) { dropbear_exit("HMAC error"); } /* the actual contents */ buf_setpos(clearwritebuf, 0); if (hmac_process(&hmac, buf_getptr(clearwritebuf, clearwritebuf->len), clearwritebuf->len) != CRYPT_OK) { dropbear_exit("HMAC error"); } hashsize = macsize; if (hmac_done(&hmac, buf_getwriteptr(outputbuffer, macsize), &hashsize) != CRYPT_OK) { dropbear_exit("HMAC error"); } buf_incrwritepos(outputbuffer, macsize); } TRACE(("leave writemac")); }
/** * 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; }
/** HMAC a block of memory to produce the authentication tag @param hash The index of the hash to use @param key The secret key @param keylen The length of the secret key (octets) @param in The data to HMAC @param inlen The length of the data to HMAC (octets) @param out [out] Destination of the authentication tag @param outlen [in/out] Max size and resulting size of authentication tag @return CRYPT_OK if successful */ int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { hmac_state *hmac; int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* allocate ram for hmac state */ hmac = XMALLOC(sizeof(hmac_state)); if (hmac == NULL) { return CRYPT_MEM; } if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(hmac, sizeof(hmac_state)); #endif XFREE(hmac); return err; }
/** * @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; }
err_status_t aes_128_cbc_hmac_sha1_96_enc(void *key, const void *clear, unsigned clear_len, void *iv, void *opaque, unsigned *opaque_len) { aes_cbc_ctx_t aes_ctx; hmac_ctx_t hmac_ctx; unsigned char enc_key[ENC_KEY_LEN]; unsigned char mac_key[MAC_KEY_LEN]; unsigned char *auth_tag; err_status_t status; /* check if we're doing authentication only */ if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { /* perform authentication only */ } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { /* * bad parameter - we expect either all three pointers to be NULL, * or none of those pointers to be NULL */ return err_status_fail; } else { #if DEBUG printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN)); #endif /* derive encryption and authentication keys from the input key */ status = hmac_init(&hmac_ctx, key, KEY_LEN); if (status) return status; status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); if (status) return status; status = hmac_init(&hmac_ctx, key, KEY_LEN); if (status) return status; status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); if (status) return status; /* perform encryption and authentication */ /* set aes key */ status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt); if (status) return status; /* set iv */ status = rand_source_get_octet_string(iv, IV_LEN); if (status) return status; status = aes_cbc_set_iv(&aes_ctx, iv); if (status) return status; #if DEBUG printf("plaintext len: %d\n", *opaque_len); printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len)); #endif #if ENC /* encrypt the opaque data */ status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); if (status) return status; #endif #if DEBUG printf("ciphertext len: %d\n", *opaque_len); printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); #endif /* * authenticate clear and opaque data, then write the * authentication tag to the location immediately following the * ciphertext */ status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); if (status) return status; status = hmac_start(&hmac_ctx); if (status) return status; status = hmac_update(&hmac_ctx, clear, clear_len); if (status) return status; #if DEBUG printf("hmac input: %s\n", octet_string_hex_string(clear, clear_len)); #endif auth_tag = (unsigned char *)opaque; auth_tag += *opaque_len; status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); if (status) return status; #if DEBUG printf("hmac input: %s\n", octet_string_hex_string(opaque, *opaque_len)); #endif /* bump up the opaque_len to reflect the authentication tag */ *opaque_len += TAG_LEN; #if DEBUG printf("prot data len: %d\n", *opaque_len); printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); #endif } return err_status_ok; }
unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) { struct crypto_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; ssh_log(session, SSH_LOG_PACKET, "Encrypting packet with seq num: %d, len: %d", session->send_seq,len); #ifdef HAVE_LIBGCRYPT if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey, session->current_crypto->encryptIV) < 0) { SAFE_FREE(out); return NULL; } #elif defined HAVE_LIBCRYPTO if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey) < 0) { SAFE_FREE(out); return NULL; } #endif if (session->version == 2) { ctx = hmac_init(session->current_crypto->encryptMAC,20,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 } #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); SAFE_FREE(out); if (session->version == 2) { return session->current_crypto->hmacbuf; } return NULL; }
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; }
int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, const unsigned char *salt, unsigned long salt_len, int iteration_count, int hash_idx, unsigned char *out, unsigned long *outlen) { int err, itts; ulong32 blkno; unsigned long stored, left, x, y; unsigned char *buf[2]; hmac_state *hmac; LTC_ARGCHK(password != NULL); LTC_ARGCHK(salt != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* test hash IDX */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } buf[0] = XMALLOC(MAXBLOCKSIZE * 2); hmac = XMALLOC(sizeof(hmac_state)); if (hmac == NULL || buf[0] == NULL) { if (hmac != NULL) { XFREE(hmac); } if (buf[0] != NULL) { XFREE(buf[0]); } return CRYPT_MEM; } /* buf[1] points to the second block of MAXBLOCKSIZE bytes */ buf[1] = buf[0] + MAXBLOCKSIZE; left = *outlen; blkno = 1; stored = 0; while (left != 0) { /* process block number blkno */ zeromem(buf[0], MAXBLOCKSIZE*2); /* store current block number and increment for next pass */ STORE32H(blkno, buf[1]); ++blkno; /* get PRF(P, S||int(blkno)) */ if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) { goto LBL_ERR; } x = MAXBLOCKSIZE; if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) { goto LBL_ERR; } /* now compute repeated and XOR it in buf[1] */ XMEMCPY(buf[1], buf[0], x); for (itts = 1; itts < iteration_count; ++itts) { if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) { goto LBL_ERR; } for (y = 0; y < x; y++) { buf[1][y] ^= buf[0][y]; } } /* now emit upto x bytes of buf[1] to output */ for (y = 0; y < x && left != 0; ++y) { out[stored++] = buf[1][y]; --left; } } *outlen = stored; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(buf[0], MAXBLOCKSIZE*2); zeromem(hmac, sizeof(hmac_state)); #endif XFREE(hmac); XFREE(buf[0]); return err; }
err_status_t aes_128_cbc_hmac_sha1_96_inv(void *key, void *clear, unsigned clear_len, void *iv, void *opaque, unsigned *opaque_len, void *auth_tag) { aes_cbc_ctx_t aes_ctx; hmac_ctx_t hmac_ctx; unsigned char enc_key[ENC_KEY_LEN]; unsigned char mac_key[MAC_KEY_LEN]; unsigned char tmp_tag[TAG_LEN]; unsigned char *tag = auth_tag; err_status_t status; int i; /* check if we're doing authentication only */ if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { /* perform authentication only */ } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { /* * bad parameter - we expect either all three pointers to be NULL, * or none of those pointers to be NULL */ return err_status_fail; } else { /* derive encryption and authentication keys from the input key */ status = hmac_init(&hmac_ctx, key, KEY_LEN); if (status) return status; status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); if (status) return status; status = hmac_init(&hmac_ctx, key, KEY_LEN); if (status) return status; status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); if (status) return status; /* perform encryption and authentication */ /* set aes key */ status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt); if (status) return status; /* set iv */ status = rand_source_get_octet_string(iv, IV_LEN); if (status) return status; status = aes_cbc_set_iv(&aes_ctx, iv); /* encrypt the opaque data */ status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len); if (status) return status; /* authenticate clear and opaque data */ status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); if (status) return status; status = hmac_start(&hmac_ctx); if (status) return status; status = hmac_update(&hmac_ctx, clear, clear_len); if (status) return status; status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag); if (status) return status; /* compare the computed tag with the one provided as input */ for (i=0; i < TAG_LEN; i++) if (tmp_tag[i] != tag[i]) return err_status_auth_fail; } return err_status_ok; }
err_status_t aes_128_cbc_hmac_sha1_96_dec(void *key, const void *clear, unsigned clear_len, void *iv, void *opaque, unsigned *opaque_len) { aes_cbc_ctx_t aes_ctx; hmac_ctx_t hmac_ctx; unsigned char enc_key[ENC_KEY_LEN]; unsigned char mac_key[MAC_KEY_LEN]; unsigned char tmp_tag[TAG_LEN]; unsigned char *auth_tag; unsigned ciphertext_len; err_status_t status; int i; /* check if we're doing authentication only */ if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { /* perform authentication only */ } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { /* * bad parameter - we expect either all three pointers to be NULL, * or none of those pointers to be NULL */ return err_status_fail; } else { #if DEBUG printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN)); #endif /* derive encryption and authentication keys from the input key */ status = hmac_init(&hmac_ctx, key, KEY_LEN); if (status) return status; status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); if (status) return status; status = hmac_init(&hmac_ctx, key, KEY_LEN); if (status) return status; status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); if (status) return status; #if DEBUG printf("prot data len: %d\n", *opaque_len); printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len)); #endif /* * set the protected data length to that of the ciphertext, by * subtracting out the length of the authentication tag */ ciphertext_len = *opaque_len - TAG_LEN; #if DEBUG printf("ciphertext len: %d\n", ciphertext_len); #endif /* verify the authentication tag */ /* * compute the authentication tag for the clear and opaque data, * and write it to a temporary location */ status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); if (status) return status; status = hmac_start(&hmac_ctx); if (status) return status; status = hmac_update(&hmac_ctx, clear, clear_len); if (status) return status; #if DEBUG printf("hmac input: %s\n", octet_string_hex_string(clear, clear_len)); #endif status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag); if (status) return status; #if DEBUG printf("hmac input: %s\n", octet_string_hex_string(opaque, ciphertext_len)); #endif /* * compare the computed tag with the one provided as input (which * immediately follows the ciphertext) */ auth_tag = (unsigned char *)opaque; auth_tag += ciphertext_len; #if DEBUG printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN)); printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN)); #endif for (i=0; i < TAG_LEN; i++) { if (tmp_tag[i] != auth_tag[i]) return err_status_auth_fail; } /* bump down the opaque_len to reflect the authentication tag */ *opaque_len -= TAG_LEN; /* decrypt the confidential data */ status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt); if (status) return status; status = aes_cbc_set_iv(&aes_ctx, iv); if (status) return status; #if DEBUG printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len)); printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN)); #endif #if ENC status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len); if (status) return status; #endif #if DEBUG printf("plaintext len: %d\n", ciphertext_len); printf("plaintext: %s\n", octet_string_hex_string(opaque, ciphertext_len)); #endif /* indicate the length of the plaintext */ *opaque_len = ciphertext_len; } return err_status_ok; }
void Decrypt(PK0304 *le, char *password) { char *salt, *key1, *key2, *check, digest[40]; u32 key_len, dig_len = 40, start, xlen; AE_EXTRA ae; start = ftell(ZIN); /* Searches for AE-1 header */ fseek(ZIN, le->NameLen, SEEK_CUR); for(xlen=le->ExtraLen; xlen;) { safeRead(&ae, ZIN, 4); xlen -= (4 + ae.Size); if (ae.Sig == 0x9901) { safeRead(&ae.Version, ZIN, 7); continue; } fseek(ZIN, ae.Size, SEEK_CUR); } if (ae.Sig != 0x9901) Z_ERROR("Fatal! Can't find AE extra header!"); if (ae.Strength < 1 || ae.Strength > 3) Z_ERROR("Bad encryption strength"); SaltSize = KS[ae.Strength].Salt; KeySize = KS[ae.Strength].Key; salt = BUF; key1 = salt+SaltSize; key2 = key1+KeySize; check = key2+KeySize; key_len = KeySize*2+2; /* Loads salt and password check value, and regenerates original crypto material */ fseek(ZIN, start+le->NameLen+le->ExtraLen, SEEK_SET); safeRead(salt, ZIN, SaltSize); safeRead(check+2, ZIN, 2); point1: if (pkcs_5_alg2(password, strlen(password), salt, SaltSize, 1000, 0, key1, &key_len) != CRYPT_OK) Z_ERROR("Failed to derive encryption keys"); if (memcmp(check, check+2, 2)) { printf("\nCan't decrypt data: try another password.\nNew password: "******"\n"); goto point1; } if (ctr_start(0, IV, key1, KeySize, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr) != CRYPT_OK) Z_ERROR("Failed to setup AES CTR decoder"); #ifdef GLADMAN_HMAC hmac_sha1_begin(&hmac); hmac_sha1_key(key2, KeySize, &hmac); #else if (hmac_init(&hmac, 0, key2, KeySize) != CRYPT_OK) Z_ERROR("Failed to setup HMAC-SHA1"); #endif /* Adjusts local header */ le->Flag ^= 1; le->CompMethod = ae.CompMethod; le->ExtraLen -= 11; le->CompSize -= (SaltSize + 12); /* Writes local header and copies extra, except 0x9901 */ safeWrite(ZOUT, le, sizeof(PK0304)); fseek(ZIN, start, SEEK_SET); fileCopy(ZOUT, ZIN, le->NameLen); for(xlen=le->ExtraLen+11; xlen;) { safeRead(&ae, ZIN, 4); xlen -= (4 + ae.Size); if (ae.Sig == 0x9901) { safeRead(&ae.Version, ZIN, 7); continue; } safeWrite(ZOUT, &ae, 4); fileCopy(ZOUT, ZIN, ae.Size); } fseek(ZIN, SaltSize+2, SEEK_CUR); fileFilter(ZOUT, ZIN, le->CompSize); #ifdef GLADMAN_HMAC hmac_sha1_end(digest, dig_len, &hmac); #else if (hmac_done(&hmac, digest, &dig_len) != CRYPT_OK) Z_ERROR("Failed to computate HMAC"); #endif /* Retrieves and checks HMACs */ safeRead(digest+10, ZIN, 10); if (memcmp(digest, digest+10, 10)) printf(" authentication failed, contents were lost!"); ctr_done(&ctr); }
err_status_t aes_128_cbc_hmac_sha1_96_func(void *key, void *clear, unsigned clear_len, void *iv, void *opaque, unsigned *opaque_len, void *auth_tag) { aes_cbc_ctx_t aes_ctx; hmac_ctx_t hmac_ctx; unsigned char enc_key[ENC_KEY_LEN]; unsigned char mac_key[MAC_KEY_LEN]; err_status_t status; /* check if we're doing authentication only */ if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) { /* perform authentication only */ } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) { /* * bad parameter - we expect either all three pointers to be NULL, * or none of those pointers to be NULL */ return err_status_fail; } else { /* derive encryption and authentication keys from the input key */ status = hmac_init(&hmac_ctx, key, KEY_LEN); if (status) return status; status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key); if (status) return status; status = hmac_init(&hmac_ctx, key, KEY_LEN); if (status) return status; status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key); if (status) return status; /* perform encryption and authentication */ /* set aes key */ status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt); if (status) return status; /* set iv */ status = crypto_get_random(iv, IV_LEN); if (status) return status; status = aes_cbc_set_iv(&aes_ctx, iv); /* encrypt the opaque data */ status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len); if (status) return status; /* authenticate clear and opaque data */ status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN); if (status) return status; status = hmac_start(&hmac_ctx); if (status) return status; status = hmac_update(&hmac_ctx, clear, clear_len); if (status) return status; status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag); if (status) return status; } return err_status_ok; }
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; enum ssh_hmac_e type; assert(len); assert(len); 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; } type = session->current_crypto->out_hmac; 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, 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); BURN_BUFFER(out, len); SAFE_FREE(out); if (session->version == 2) { return session->current_crypto->hmacbuf; } return NULL; }