Ejemplo n.º 1
0
/**
 * Update the HMAC_DRBG key
 *
 * @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
 *
 *     K = HMAC ( K, V || single || provided_data )
 *
 * as used by hmac_drbg_update()
 */
static void hmac_drbg_update_key ( struct digest_algorithm *hash,
				   struct hmac_drbg_state *state,
				   const void *data, size_t len,
				   const uint8_t single ) {
	uint8_t context[ hash->ctxsize ];
	size_t out_len = hash->digestsize;

	DBGC ( state, "HMAC_DRBG_%s %p provided data :\n", hash->name, state );
	DBGC_HDA ( state, 0, data, len );

	/* Sanity checks */
	assert ( hash != NULL );
	assert ( state != NULL );
	assert ( ( data != NULL ) || ( len == 0 ) );
	assert ( ( single == 0x00 ) || ( single == 0x01 ) );

	/* K = HMAC ( K, V || single || provided_data ) */
	hmac_init ( hash, context, state->key, &out_len );
	assert ( out_len == hash->digestsize );
	hmac_update ( hash, context, state->value, out_len );
	hmac_update ( hash, context, &single, sizeof ( single ) );
	hmac_update ( hash, context, data, len );
	hmac_final ( hash, context, state->key, &out_len, state->key );
	assert ( out_len == hash->digestsize );

	DBGC ( state, "HMAC_DRBG_%s %p K = HMAC ( K, V || %#02x || "
	       "provided_data ) :\n", hash->name, state, single );
	DBGC_HDA ( state, 0, state->key, out_len );
}
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) {
  unsigned char hmacbuf[EVP_MAX_MD_SIZE] = {0};
  HMACCTX ctx;
  unsigned int len;
  uint32_t seq;

  ctx = hmac_init(session->current_crypto->decryptMAC, 20, SSH_HMAC_SHA1);
  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
void pbkdf(buffer password, buffer salt, word block_index, int rounds, buffer *key) {
	assert(key->length == 32);

	hmac base_mac = hmac_init(password), mac;
	buffer temp = buffer_calloc(32);

	// First iteration
	// U1 = HMAC(P, S || (i+1))
	mac = hmac_clone(base_mac);
	hmac_update(&mac, salt);
	buffer index = buffer_calloc(4); // 1 word
	index.words[0] = block_index+1;
	hmac_update(&mac, index);
	buffer_free(&index);
	hmac_end(&mac, key);
	buffer_copy(&temp, *key);

	// Next iterations
	// U_(n+1) = U_n ^ HMAC(P, U_n)
	for (int i=1; i<rounds; i++) {
		mac = hmac_clone(base_mac);
		hmac_update(&mac, temp);
		hmac_end(&mac, &temp);
		buffer_xor(key, temp);
	}

	buffer_free(&temp);
	hmac_free(&base_mac);
}
Ejemplo n.º 4
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.º 5
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.º 6
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.º 7
0
/*
 * Assumes: prng != NULL, e != NULL, len >= 0.
 */
static void update (HmacPrng_t prng, const uint8_t *e, uint32_t len) {
  const uint8_t separator0 = 0x00;
  const uint8_t separator1 = 0x01;

  /* use current state, e and separator 0 to compute a new prng key: */
  (void) hmac_init (&prng->h);
  (void) hmac_update (&prng->h, prng->v, sizeof (prng->v));
  (void) hmac_update (&prng->h, &separator0, sizeof (separator0));
  (void) hmac_update (&prng->h, e, len);
  (void) hmac_final (prng->key, sizeof(prng->key), &prng->h);
  /* configure the new prng key into the prng's instance of hmac */
  (void) hmac_set_key (&prng->h, prng->key, sizeof (prng->key));

  /* use the new key to compute a new state variable v */
  (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);

  /* use current state, e and separator 1 to compute a new prng key: */
  (void) hmac_init (&prng->h);
  (void) hmac_update (&prng->h, prng->v, sizeof (prng->v));
  (void) hmac_update (&prng->h, &separator1, sizeof (separator1));
  (void) hmac_update (&prng->h, e, len);
  (void) hmac_final (prng->key, sizeof(prng->key), &prng->h);
  /* configure the new prng key into the prng's instance of hmac */
  (void) hmac_set_key (&prng->h, prng->key, sizeof (prng->key));

  /* use the new key to compute a new state variable v */
  (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);
}
Ejemplo n.º 8
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.º 9
0
/**
 * Report server passphrase test result
 *
 * @v test		Content information segment test
 * @v info		Content information
 * @v pass		Server passphrase
 * @v pass_len		Length of server passphrase
 * @v file		Test code file
 * @v line		Test code line
 */
static void
peerdist_info_passphrase_okx ( struct peerdist_info_segment_test *test,
			       const struct peerdist_info *info,
			       uint8_t *pass, size_t pass_len,
			       const char *file, unsigned int line ) {
	struct digest_algorithm *digest = info->digest;
	uint8_t ctx[digest->ctxsize];
	uint8_t secret[digest->digestsize];
	uint8_t expected[digest->digestsize];
	size_t digestsize = info->digestsize;
	size_t secretsize = digestsize;

	/* Calculate server secret */
	digest_init ( digest, ctx );
	digest_update ( digest, ctx, pass, pass_len );
	digest_final ( digest, ctx, secret );

	/* Calculate expected segment secret */
	hmac_init ( digest, ctx, secret, &secretsize );
	assert ( secretsize == digestsize );
	hmac_update ( digest, ctx, test->expected_hash, digestsize );
	hmac_final ( digest, ctx, secret, &secretsize, expected );
	assert ( secretsize == digestsize );

	/* Verify segment secret */
	okx ( memcmp ( test->expected_secret, expected, digestsize ) == 0,
	      file, line );
}
Ejemplo n.º 10
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, AUTH_SUBSYS_MECH,
                               "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, AUTH_SUBSYS_MECH,
                              "password mismatch");
        return FALSE;
    }

    return TRUE;
}
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
/**
 * Generate secure pseudo-random data using a single hash function
 *
 * @v tls		TLS session
 * @v digest		Hash function to use
 * @v secret		Secret
 * @v secret_len	Length of secret
 * @v out		Output buffer
 * @v out_len		Length of output buffer
 * @v seeds		( data, len ) pairs of seed data, terminated by NULL
 */
static void tls_p_hash_va ( struct tls_session *tls,
			    struct digest_algorithm *digest,
			    void *secret, size_t secret_len,
			    void *out, size_t out_len,
			    va_list seeds ) {
	uint8_t secret_copy[secret_len];
	uint8_t digest_ctx[digest->ctxsize];
	uint8_t digest_ctx_partial[digest->ctxsize];
	uint8_t a[digest->digestsize];
	uint8_t out_tmp[digest->digestsize];
	size_t frag_len = digest->digestsize;
	va_list tmp;

	/* Copy the secret, in case HMAC modifies it */
	memcpy ( secret_copy, secret, secret_len );
	secret = secret_copy;
	DBGC2 ( tls, "TLS %p %s secret:\n", tls, digest->name );
	DBGC2_HD ( tls, secret, secret_len );

	/* Calculate A(1) */
	hmac_init ( digest, digest_ctx, secret, &secret_len );
	va_copy ( tmp, seeds );
	tls_hmac_update_va ( digest, digest_ctx, tmp );
	va_end ( tmp );
	hmac_final ( digest, digest_ctx, secret, &secret_len, a );
	DBGC2 ( tls, "TLS %p %s A(1):\n", tls, digest->name );
	DBGC2_HD ( tls, &a, sizeof ( a ) );

	/* Generate as much data as required */
	while ( out_len ) {
		/* Calculate output portion */
		hmac_init ( digest, digest_ctx, secret, &secret_len );
		hmac_update ( digest, digest_ctx, a, sizeof ( a ) );
		memcpy ( digest_ctx_partial, digest_ctx, digest->ctxsize );
		va_copy ( tmp, seeds );
		tls_hmac_update_va ( digest, digest_ctx, tmp );
		va_end ( tmp );
		hmac_final ( digest, digest_ctx,
			     secret, &secret_len, out_tmp );

		/* Copy output */
		if ( frag_len > out_len )
			frag_len = out_len;
		memcpy ( out, out_tmp, frag_len );
		DBGC2 ( tls, "TLS %p %s output:\n", tls, digest->name );
		DBGC2_HD ( tls, out, frag_len );

		/* Calculate A(i) */
		hmac_final ( digest, digest_ctx_partial,
			     secret, &secret_len, a );
		DBGC2 ( tls, "TLS %p %s A(n):\n", tls, digest->name );
		DBGC2_HD ( tls, &a, sizeof ( a ) );

		out += frag_len;
		out_len -= frag_len;
	}
}
Ejemplo n.º 13
0
/****************************************************************************
 *
 * Open an OSAP session
 * Object Specific Authorization Protocol, returned handle must manipulate
 * a single object given as a parameter (can introduce AuthData).
 *                                                                          *
 ****************************************************************************/
uint32_t TSS_OSAPopen(struct tss_osapsess *sess, const uint8_t *key, uint16_t etype,
		      uint32_t evalue)
{
	struct s_tpm_osap_open_cmd cmd;
	uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
	uint32_t nonceSize;
	uint32_t result;

	debug("TPM: TSS_OSAPopen\n");
	/* check input arguments */
	if (key == NULL || sess == NULL) {
		return TPM_E_NULL_ARG;
	}

	TlclGetRandom(sess->ononceOSAP, TPM_NONCE_SIZE, &nonceSize);

	memcpy(&cmd, &tpm_osap_open_cmd, sizeof(cmd));
	ToTpmUint16(cmd.buffer + tpm_osap_open_cmd.type, etype);
	ToTpmUint32(cmd.buffer + tpm_osap_open_cmd.value, evalue);
	memcpy(cmd.buffer + tpm_osap_open_cmd.nonce, sess->ononceOSAP, TPM_NONCE_SIZE);

	result = TlclSendReceive(cmd.buffer, response, sizeof(response));

	if (result == TPM_SUCCESS) {
		FromTpmUint32(response + kTpmResponseHeaderLength, &(sess->handle));
		memcpy(sess->enonce, response + kTpmResponseHeaderLength + sizeof(uint32_t), TPM_NONCE_SIZE);
		memcpy(sess->enonceOSAP, response + kTpmResponseHeaderLength + sizeof(uint32_t) + TPM_NONCE_SIZE, TPM_NONCE_SIZE);

		debug("TPM: TSS_OSAPopen success, calculating HMAC\n");
		/*DATA_DEBUG("key", key, TPM_HASH_SIZE);
		DATA_DEBUG("enonceOSAP", sess->enonceOSAP, TPM_NONCE_SIZE);
		DATA_DEBUG("ononceOSAP", sess->ononceOSAP, TPM_NONCE_SIZE);*/

		/* not implemented */
		SHA1_CTX hmac;
		hmac_starts(&hmac, key, TPM_HASH_SIZE);
		hmac_update(&hmac, sess->enonceOSAP, TPM_NONCE_SIZE);
		hmac_update(&hmac, sess->ononceOSAP, TPM_NONCE_SIZE);
		hmac_finish(&hmac, key, TPM_HASH_SIZE, sess->ssecret);
	}

	return result;
}
Ejemplo n.º 14
0
/**
 * Update HMAC with a list of ( data, len ) pairs
 *
 * @v digest		Hash function to use
 * @v digest_ctx	Digest context
 * @v args		( data, len ) pairs of data, terminated by NULL
 */
static void tls_hmac_update_va ( struct digest_algorithm *digest,
				 void *digest_ctx, va_list args ) {
	void *data;
	size_t len;

	while ( ( data = va_arg ( args, void * ) ) ) {
		len = va_arg ( args, size_t );
		hmac_update ( digest, digest_ctx, data, 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
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.º 17
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.º 18
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.º 19
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.º 20
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.º 21
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.º 22
0
void v2prfplus(struct v2prf_stuff *vps)
{
	struct hmac_ctx ctx;

	hmac_init_chunk(&ctx, vps->prf_hasher, *vps->skeyseed);
	hmac_update_chunk(&ctx, vps->t);
	hmac_update_chunk(&ctx, vps->ni);
	hmac_update_chunk(&ctx, vps->nr);
	hmac_update_chunk(&ctx, vps->spii);
	hmac_update_chunk(&ctx, vps->spir);
	hmac_update(&ctx, vps->counter, 1);
	hmac_final_chunk(vps->t, "skeyseed_t1", &ctx);
	DBG(DBG_CRYPT, {
		    char b[20];
		    sprintf(b, "prf+[%u]:", vps->counter[0]);
		    DBG_dump_chunk(b, vps->t);
	    });
Ejemplo n.º 23
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.º 24
0
Archivo: hmac.c Proyecto: dozeo/libsrtp
err_status_t
hmac_compute(hmac_ctx_t *state, const void *message,
	     int msg_octets, int tag_len, uint8_t *result) {
  uint32_t hash_value[5];
  uint32_t H[5];
  int i;

  /* check tag length, return error if we can't provide the value expected */
  if (tag_len > 20)
    return err_status_bad_param;
  
  /* hash message, copy output into H */
  hmac_update(state, (const uint8_t*)message, msg_octets);
  sha1_final(&state->ctx, H);

  /*
   * note that we don't need to debug_print() the input, since the
   * function hmac_update() already did that for us
   */
  debug_print(mod_hmac, "intermediate state: %s", 
	      octet_string_hex_string((uint8_t *)H, 20));

  /* re-initialize hash context */
  sha1_init(&state->ctx);
  
  /* hash opad ^ key  */
  sha1_update(&state->ctx, (uint8_t *)state->opad, 64);

  /* hash the result of the inner hash */
  sha1_update(&state->ctx, (uint8_t *)H, 20);
  
  /* the result is returned in the array hash_value[] */
  sha1_final(&state->ctx, hash_value);

  /* copy hash_value to *result */
  for (i=0; i < tag_len; i++)    
    result[i] = ((uint8_t *)hash_value)[i];

  debug_print(mod_hmac, "output: %s", 
	      octet_string_hex_string((uint8_t *)hash_value, tag_len));

  return err_status_ok;
}
Ejemplo n.º 25
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.º 26
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.º 27
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.º 28
0
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;
}
Ejemplo n.º 29
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;
}
Ejemplo n.º 30
0
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;
}