Example #1
0
/**
   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;
}
Example #2
0
/**
  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
}
Example #3
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);
}
Example #4
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 );
}
Example #5
0
/* 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;
	}
}
Example #6
0
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
}
Example #7
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));
}
Example #8
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;
}
Example #9
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;
}
Example #10
0
/* 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"));
}
Example #11
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 );
}
Example #12
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;
}
Example #13
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;
}
/**
   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;   
}
Example #15
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;
}
Example #16
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;
}
Example #17
0
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;
}
Example #18
0
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;
}
Example #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;
}
Example #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;
}
Example #21
0
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;
}
Example #22
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;
}
Example #23
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;
}
Example #24
0
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);
}
Example #25
0
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;
}
Example #26
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;
  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;
}