static int
wrap_padlock_hmac_fast (gnutls_mac_algorithm_t algo,
                        const void *key, size_t key_size, const void *text,
                        size_t text_size, void *digest)
{
    if (algo == GNUTLS_MAC_SHA1 || algo == GNUTLS_MAC_SHA256)
      {
          unsigned char *pad;
          unsigned char pad2[SHA1_DATA_SIZE + MAX_SHA_DIGEST_SIZE];
          unsigned char hkey[MAX_SHA_DIGEST_SIZE];
          unsigned int digest_size = _gnutls_hmac_get_algo_len (algo);

          if (key_size > SHA1_DATA_SIZE)
            {
                wrap_padlock_hash_fast (algo, key, key_size, hkey);
                key = hkey;
                key_size = digest_size;
            }

          pad = gnutls_malloc (text_size + SHA1_DATA_SIZE);
          if (pad == NULL)
              return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);

          memset (pad, IPAD, SHA1_DATA_SIZE);
          memxor (pad, key, key_size);

          memcpy (&pad[SHA1_DATA_SIZE], text, text_size);

          wrap_padlock_hash_fast (algo, pad, text_size + SHA1_DATA_SIZE,
                                  &pad2[SHA1_DATA_SIZE]);

          gnutls_free (pad);

          memset (pad2, OPAD, SHA1_DATA_SIZE);
          memxor (pad2, key, key_size);

          wrap_padlock_hash_fast (algo, pad2, digest_size + SHA1_DATA_SIZE,
                                  digest);

      }
    else
      {
          struct padlock_hmac_ctx ctx;
          int ret;

          ret = _hmac_ctx_init (algo, &ctx);
          if (ret < 0)
              return gnutls_assert_val (ret);
          ctx.algo = algo;

          wrap_padlock_hmac_setkey (&ctx, key, key_size);

          wrap_padlock_hmac_update (&ctx, text, text_size);

          wrap_padlock_hmac_output (&ctx, digest, ctx.length);
      }

    return 0;
}
Example #2
0
int
_gnutls_epoch_set_keys (gnutls_session_t session, uint16_t epoch)
{
  int hash_size;
  int IV_size;
  int key_size, export_flag;
  gnutls_cipher_algorithm_t cipher_algo;
  gnutls_mac_algorithm_t mac_algo;
  gnutls_compression_method_t comp_algo;
  record_parameters_st *params;
  int ret;
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

  ret = _gnutls_epoch_get (session, epoch, &params);
  if (ret < 0)
    return gnutls_assert_val (ret);

  if (params->initialized)
    return 0;

  _gnutls_record_log
    ("REC[%p]: Initializing epoch #%u\n", session, params->epoch);

  cipher_algo = params->cipher_algorithm;
  mac_algo = params->mac_algorithm;
  comp_algo = params->compression_algorithm;

  if (_gnutls_cipher_is_ok (cipher_algo) != 0
      || _gnutls_mac_is_ok (mac_algo) != 0)
    return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR);

  if (_gnutls_compression_is_ok (comp_algo) != 0)
    return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM);

  IV_size = _gnutls_cipher_get_iv_size (cipher_algo);
  key_size = gnutls_cipher_get_key_size (cipher_algo);
  export_flag = _gnutls_cipher_get_export_flag (cipher_algo);
  hash_size = _gnutls_hmac_get_algo_len (mac_algo);

  ret = _gnutls_set_keys
    (session, params, hash_size, IV_size, key_size, export_flag);
  if (ret < 0)
    return gnutls_assert_val (ret);

  ret = _gnutls_init_record_state (params, ver, 1, &params->read);
  if (ret < 0)
    return gnutls_assert_val (ret);

  ret = _gnutls_init_record_state (params, ver, 0, &params->write);
  if (ret < 0)
    return gnutls_assert_val (ret);

  params->record_sw_size = 0;

  _gnutls_record_log ("REC[%p]: Epoch #%u ready\n", session, params->epoch);

  params->initialized = 1;
  return 0;
}
Example #3
0
/* returns overhead imposed by the record layer (encryption/compression)
 * etc. It does not include the record layer headers, since the caller
 * needs to cope with rounding to multiples of blocksize, and the header
 * is outside that.
 *
 * blocksize: will contain the block size when padding may be required or 1
 *
 * It may return a negative error code on error.
 */
static int record_overhead_rt(gnutls_session_t session, unsigned int *blocksize)
{
record_parameters_st *params;
int total = 0, ret, iv_size;

  if (session->internals.initial_negotiation_completed == 0)
    return GNUTLS_E_INVALID_REQUEST;

  ret = _gnutls_epoch_get (session, EPOCH_WRITE_CURRENT, &params);
  if (ret < 0)
    return gnutls_assert_val(ret);

  /* requires padding */
  iv_size = _gnutls_cipher_get_iv_size(params->cipher_algorithm);

  if (_gnutls_cipher_is_block (params->cipher_algorithm) == CIPHER_BLOCK)
    {
      *blocksize = iv_size;

      total += iv_size; /* iv_size == block_size in DTLS */

      /* We always pad with at least one byte; never 0. */
      total++;
    }
  else
    {
      *blocksize = 1;
    }
  
  if (params->mac_algorithm == GNUTLS_MAC_AEAD)
    total += _gnutls_cipher_get_tag_size(params->cipher_algorithm);
  else
    {
      ret = _gnutls_hmac_get_algo_len(params->mac_algorithm);
      if (ret < 0)
        return gnutls_assert_val(ret);
      total+=ret;
    }

  if (params->compression_algorithm != GNUTLS_COMP_NULL)
    total += EXTRA_COMP_SIZE;

  return total;
}