Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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 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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
/**
 * 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 );
}
Ejemplo n.º 11
0
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));
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
/**
 * 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 );
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
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;
}