Beispiel #1
0
/*********************** FUNCTION DEFINITIONS ***********************/
int md2_test()
{
	BYTE text1[] = {"abc"};
	BYTE text2[] = {"abcdefghijklmnopqrstuvwxyz"};
	BYTE text3_1[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"};
	BYTE text3_2[] = {"fghijklmnopqrstuvwxyz0123456789"};
	BYTE hash1[MD2_BLOCK_SIZE] = {0xda,0x85,0x3b,0x0d,0x3f,0x88,0xd9,0x9b,0x30,0x28,0x3a,0x69,0xe6,0xde,0xd6,0xbb};
	BYTE hash2[MD2_BLOCK_SIZE] = {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b};
	BYTE hash3[MD2_BLOCK_SIZE] = {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd};
	BYTE buf[16];
	MD2_CTX ctx;
	int pass = 1;

	md2_init(&ctx);
	md2_update(&ctx, text1, strlen(text1));
	md2_final(&ctx, buf);
	pass = pass && !memcmp(hash1, buf, MD2_BLOCK_SIZE);

	// Note that the MD2 object can be re-used.
	md2_init(&ctx);
	md2_update(&ctx, text2, strlen(text2));
	md2_final(&ctx, buf);
	pass = pass && !memcmp(hash2, buf, MD2_BLOCK_SIZE);

	// Note that the data is added in two chunks.
	md2_init(&ctx);
	md2_update(&ctx, text3_1, strlen(text3_1));
	md2_update(&ctx, text3_2, strlen(text3_2));
	md2_final(&ctx, buf);
	pass = pass && !memcmp(hash3, buf, MD2_BLOCK_SIZE);

	return(pass);
}
Beispiel #2
0
/**
 * MD2 test fuction.
 * This function test MD2 algorithm with a standard string specified
 * in RFC 1319.
 *
 * \note This test work with official array of 256 byte pemutation
 * contructed from digits of pi, defined in the RFC 1319.
 *
 */
bool md2_test(void)
{

	Md2Context context;

	const char *test[] =
	{
		"",
		"message digest",
		"abcdefghijklmnopqrstuvwxyz",
		"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
	};


	const char *result[] = {
		"\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73",
		"\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0",
		"\x4e\x8d\xdf\xf3\x65\x02\x92\xab\x5a\x41\x08\xc3\xaa\x47\x94\x0b",
		"\xd5\x97\x6f\x79\xd8\x3d\x3a\x0d\xc9\x80\x6c\x3c\x66\xf3\xef\xd8",
	};


	for (size_t i = 0; i < countof(test); i++)
	{
		md2_init(&context);
		md2_update(&context, test[i], strlen(test[i]));

		if(memcmp(result[i], md2_end(&context), MD2_DIGEST_LEN))
			return false;
	}

	return true;
}
Beispiel #3
0
/*
 * This function stir entropy pool with MD2 function hash.
 *
 */
static void randpool_stir(EntropyPool *pool)
{
	size_t entropy = pool->entropy; //Save current calue of entropy.
	Md2Context context;
	uint8_t tmp_buf[((sizeof(size_t) * 2) + sizeof(int)) * 2 + 1]; //Temporary buffer.

	md2_init(&context); //Init MD2 algorithm.

	randpool_add(pool, NULL, 0);

	for (int i = 0; i < (CONFIG_SIZE_ENTROPY_POOL / MD2_DIGEST_LEN); i++)
	{
		sprintf((char *)tmp_buf, "%0x%0x%0x", pool->counter, i, pool->pos_add);

		/*
		 * Hash with MD2 algorithm the entropy pool.
		 */
		md2_update(&context, pool->pool_entropy, CONFIG_SIZE_ENTROPY_POOL);

		md2_update(&context, tmp_buf, sizeof(tmp_buf) - 1);

		/*Insert a message digest in entropy pool.*/
		randpool_push(pool, md2_end(&context), MD2_DIGEST_LEN);

		pool->counter = pool->counter + 1;

	}

	/*Insert in pool the difference between a two call of this function (see above).*/
	randpool_add(pool, NULL, 0);

	pool->entropy = entropy; //Restore old value of entropy. We haven't add entropy.
}
Beispiel #4
0
/*
 * output = MD2( file contents )
 */
int md2_file( const char *path, unsigned char output[16] )
{
    FILE *f;
    size_t n;
    md2_context ctx;
    unsigned char buf[1024];

    if( ( f = fopen( path, "rb" ) ) == NULL )
        return( POLARSSL_ERR_MD2_FILE_IO_ERROR );

    md2_init( &ctx );
    md2_starts( &ctx );

    while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
        md2_update( &ctx, buf, n );

    md2_finish( &ctx, output );
    md2_free( &ctx );

    if( ferror( f ) != 0 )
    {
        fclose( f );
        return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
    }

    fclose( f );
    return( 0 );
}
Beispiel #5
0
/**
  Self-test the hash
  @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int md2_test(void)
{
 #ifndef LTC_TEST
    return CRYPT_NOP;
 #else
   static const struct {
        const char *msg;
        unsigned char hash[16];
   } tests[] = {
      { "",
        {0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,
         0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73
        }
      },
      { "a",
        {0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,
         0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1
        }
      },
      { "message digest",
        {0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,
         0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0
        }
      },
      { "abcdefghijklmnopqrstuvwxyz",
        {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,
         0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b
        }
      },
      { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
        {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,
         0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd
        }
      },
      { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
        {0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,
         0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8
        }
      }
   };

   int i;
   unsigned char tmp[16];
   hash_state md;

   for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
       md2_init(&md);
       md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
       md2_done(&md, tmp);
       if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "MD2", i)) {
          return CRYPT_FAIL_TESTVECTOR;
       }
   }
   return CRYPT_OK;
  #endif
}
Beispiel #6
0
void calc_md2(char *str,uint8_t *digest,uint8_t *message,int32_t len)
{
    int init_hexbytes_noT(char *hexbytes,unsigned char *message,long len);
    hash_state md;
    md2_init(&md);
    md2_process(&md,message,len);
    md2_done(&md,digest);
    if ( str != 0 )
        init_hexbytes_noT(str,digest,16);
}
Beispiel #7
0
/*
 * output = MD2( input buffer )
 */
void md2( const unsigned char *input, size_t ilen, unsigned char output[16] )
{
    md2_context ctx;

    md2_init( &ctx );
    md2_starts( &ctx );
    md2_update( &ctx, input, ilen );
    md2_finish( &ctx, output );
    md2_free( &ctx );
}
Beispiel #8
0
void
md2_digest(struct md2_ctx *ctx,
	   unsigned length,
	   uint8_t *digest)
{
  unsigned left;
  
  assert(length <= MD2_DIGEST_SIZE);

  left = MD2_DATA_SIZE - ctx->index;
  memset(ctx->block + ctx->index, left, left);
  md2_transform(ctx, ctx->block);
  
  md2_transform(ctx, ctx->C);
  memcpy(digest, ctx->X, length);
  md2_init(ctx);
}
Beispiel #9
0
/**
 * Get \param n_byte from entropy pool. If n_byte is larger than number
 * byte of entropy in entropy pool, randpool_get continue
 * to generate pseudocasual value from previous state of
 * pool.
 * \param n_byte number fo bytes to read.
 * \param pool is the pool entropy context.
 * \param _data is the pointer to write the random data to.
 */
void randpool_get(EntropyPool *pool, void *_data, size_t n_byte)
{
	Md2Context context;
	size_t i = pool->pos_get;
	size_t n = n_byte;
	size_t pos_write = 0;  //Number of block has been written in data.
	size_t len = MIN((size_t)MD2_DIGEST_LEN, n_byte);
	uint8_t *data;

	data = (uint8_t *)_data;

	/* Test if i + CONFIG_MD2_BLOCK_LEN  is inside of entropy pool.*/
	ASSERT((MD2_DIGEST_LEN + i) <= CONFIG_SIZE_ENTROPY_POOL);

	md2_init(&context);

	while(n > 0)
	{

		/*Hash previous state of pool*/
		md2_update(&context, &pool->pool_entropy[i], MD2_DIGEST_LEN);

		memcpy(&data[pos_write], md2_end(&context), len);

		pos_write += len;   //Update number of block has been written in data.
		n -= len;           //Number of byte copied in data.

		len = MIN(n,(size_t)MD2_DIGEST_LEN);

		i = (i + MD2_DIGEST_LEN) % CONFIG_SIZE_ENTROPY_POOL;

		/* If we haven't more entropy pool to hash, we stir it.*/
		if(i < MD2_DIGEST_LEN)
		{
			randpool_stir(pool);
			i = pool->pos_get;
		}

	}

	pool->pos_get = i; //Current number of byte we get from pool.
	pool->entropy -= n_byte; //Update a entropy.

}
Beispiel #10
0
static NTSTATUS hash_init( struct hash_impl *hash, enum alg_id alg_id )
{
    switch (alg_id)
    {
    case ALG_ID_MD2:
        md2_init( &hash->u.md2 );
        break;

    case ALG_ID_MD4:
        MD4Init( &hash->u.md4 );
        break;

    case ALG_ID_MD5:
        MD5Init( &hash->u.md5 );
        break;

    case ALG_ID_SHA1:
        A_SHAInit( &hash->u.sha1 );
        break;

    case ALG_ID_SHA256:
        sha256_init( &hash->u.sha256 );
        break;

    case ALG_ID_SHA384:
        sha384_init( &hash->u.sha512 );
        break;

    case ALG_ID_SHA512:
        sha512_init( &hash->u.sha512 );
        break;

    default:
        ERR( "unhandled id %u\n", alg_id );
        return STATUS_NOT_IMPLEMENTED;
    }
    return STATUS_SUCCESS;
}
Beispiel #11
0
Datei: mac.c Projekt: ares89/vlc
static int
wrap_nettle_hash_init (gnutls_mac_algorithm_t algo, void **_ctx)
{
  struct nettle_hash_ctx *ctx;

  ctx = gnutls_malloc (sizeof (struct nettle_hash_ctx));
  if (ctx == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  ctx->algo = algo;

  switch (algo)
    {
    case GNUTLS_DIG_MD5:
      md5_init (&ctx->ctx.md5);
      ctx->update = (update_func) md5_update;
      ctx->digest = (digest_func) md5_digest;
      ctx->ctx_ptr = &ctx->ctx.md5;
      ctx->length = MD5_DIGEST_SIZE;
      break;
    case GNUTLS_DIG_SHA1:
      sha1_init (&ctx->ctx.sha1);
      ctx->update = (update_func) sha1_update;
      ctx->digest = (digest_func) sha1_digest;
      ctx->ctx_ptr = &ctx->ctx.sha1;
      ctx->length = SHA1_DIGEST_SIZE;
      break;
    case GNUTLS_DIG_MD2:
      md2_init (&ctx->ctx.md2);
      ctx->update = (update_func) md2_update;
      ctx->digest = (digest_func) md2_digest;
      ctx->ctx_ptr = &ctx->ctx.md2;
      ctx->length = MD2_DIGEST_SIZE;
      break;
    case GNUTLS_DIG_SHA224:
      sha224_init (&ctx->ctx.sha224);
      ctx->update = (update_func) sha224_update;
      ctx->digest = (digest_func) sha224_digest;
      ctx->ctx_ptr = &ctx->ctx.sha224;
      ctx->length = SHA224_DIGEST_SIZE;
      break;
    case GNUTLS_DIG_SHA256:
      sha256_init (&ctx->ctx.sha256);
      ctx->update = (update_func) sha256_update;
      ctx->digest = (digest_func) sha256_digest;
      ctx->ctx_ptr = &ctx->ctx.sha256;
      ctx->length = SHA256_DIGEST_SIZE;
      break;
    case GNUTLS_DIG_SHA384:
      sha384_init (&ctx->ctx.sha384);
      ctx->update = (update_func) sha384_update;
      ctx->digest = (digest_func) sha384_digest;
      ctx->ctx_ptr = &ctx->ctx.sha384;
      ctx->length = SHA384_DIGEST_SIZE;
      break;
    case GNUTLS_DIG_SHA512:
      sha512_init (&ctx->ctx.sha512);
      ctx->update = (update_func) sha512_update;
      ctx->digest = (digest_func) sha512_digest;
      ctx->ctx_ptr = &ctx->ctx.sha512;
      ctx->length = SHA512_DIGEST_SIZE;
      break;
    default:
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  *_ctx = ctx;

  return 0;
}
Beispiel #12
0
int
assemble_ipmi_lan_pkt (fiid_obj_t obj_rmcp_hdr,
                       fiid_obj_t obj_lan_session_hdr,
                       fiid_obj_t obj_lan_msg_hdr,
                       fiid_obj_t obj_cmd,
                       const void *authentication_code_data,
                       unsigned int authentication_code_data_len,
                       void *pkt,
                       unsigned int pkt_len,
		       unsigned int flags)
{
  uint8_t authentication_type;
  uint64_t val;
  unsigned int indx = 0;
  int required_len;
  void *authentication_code_field_ptr = NULL;
  void *checksum_data_ptr = NULL;
  void *msg_data_ptr = NULL;
  void *ipmi_msg_len_ptr = NULL;
  unsigned int msg_data_count = 0;
  unsigned int checksum_data_count = 0;
  uint8_t ipmi_msg_len;
  fiid_obj_t obj_lan_msg_trlr = NULL;
  uint8_t pwbuf[IPMI_1_5_MAX_PASSWORD_LENGTH];
  uint8_t checksum;
  int len, rv = -1;
  unsigned int flags_mask = 0;

  if (!fiid_obj_valid (obj_rmcp_hdr)
      || !fiid_obj_valid (obj_lan_session_hdr)
      || !fiid_obj_valid (obj_lan_msg_hdr)
      || !fiid_obj_valid (obj_cmd)
      || (authentication_code_data && authentication_code_data_len > IPMI_1_5_MAX_PASSWORD_LENGTH)
      || !pkt
      || (flags & ~flags_mask))
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_session_hdr, tmpl_lan_session_hdr) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_msg_hdr, tmpl_lan_msg_hdr_rq) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }

  if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      return (-1);
    }

  /*
   * ipmi_msg_len is calculated in this function, so we can't use
   * fiid_obj_packet_valid() on obj_lan_session_hdr b/c ipmi_msg_len
   * is probably not set yet.
   */

  if (FIID_OBJ_PACKET_VALID (obj_lan_msg_hdr) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      return (-1);
    }
  if (FIID_OBJ_PACKET_VALID (obj_cmd) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      return (-1);
    }

  if (FIID_OBJ_GET (obj_lan_session_hdr,
                    "authentication_type",
                    &val) < 0)
    {
      ERRNO_TRACE (errno);
      return (-1);
    }
  authentication_type = val;

  if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE
      && authentication_type != IPMI_AUTHENTICATION_TYPE_MD2
      && authentication_type != IPMI_AUTHENTICATION_TYPE_MD5
      && authentication_type != IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY)
    {
      SET_ERRNO (EINVAL);
      return (-1);
    }

  /* no need for overflow checks, handled w/ _ipmi_lan_pkt_rq_min_size check */

  required_len = _ipmi_lan_pkt_rq_min_size (authentication_type, obj_cmd);
  if (pkt_len < required_len)
    {
      SET_ERRNO (EMSGSIZE);
      return (-1);
    }

  memset (pkt, 0, pkt_len);

  if ((len = fiid_obj_get_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr);
      goto cleanup;
    }
  indx += len;

  if ((len = fiid_obj_get_block (obj_lan_session_hdr,
                                 "authentication_type",
                                 "session_id",
                                 pkt + indx,
                                 pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
      goto cleanup;
    }

  indx += len;

  /* authentication_code generated last.  Save pointers for later calculation */
  if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE)
    {
      authentication_code_field_ptr = (pkt + indx);
      indx += IPMI_1_5_MAX_PASSWORD_LENGTH;
    }

  ipmi_msg_len_ptr = (pkt + indx);
  if ((len = fiid_template_field_len_bytes (tmpl_lan_session_hdr, "ipmi_msg_len")) < 0)
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }
  if (len != 1)
    {
      SET_ERRNO (EINVAL);
      goto cleanup;
    }
  indx += len;

  msg_data_ptr = (pkt + indx);

  if ((len = fiid_obj_get_block (obj_lan_msg_hdr,
                                 "rs_addr",
                                 "checksum1",
                                 pkt + indx,
                                 pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      goto cleanup;
    }
  indx += len;
  msg_data_count += len;

  checksum_data_ptr = (pkt + indx);

  if ((len = fiid_obj_get_block (obj_lan_msg_hdr,
                                 "rq_addr",
                                 "rq_seq",
                                 pkt + indx,
                                 pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr);
      goto cleanup;
    }
  indx += len;
  msg_data_count += len;
  checksum_data_count += len;

  if ((len = fiid_obj_get_all (obj_cmd, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd);
      goto cleanup;
    }
  indx += len;
  msg_data_count += len;
  checksum_data_count += len;

  if (!(obj_lan_msg_trlr = fiid_obj_create (tmpl_lan_msg_trlr)))
    {
      ERRNO_TRACE (errno);
      goto cleanup;
    }

  checksum = ipmi_checksum (checksum_data_ptr, checksum_data_count);

  if (fiid_obj_set_all (obj_lan_msg_trlr, &checksum, sizeof (checksum)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr);
      goto cleanup;
    }

  if ((len = fiid_obj_get_all (obj_lan_msg_trlr, pkt + indx, pkt_len - indx)) < 0)
    {
      FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr);
      goto cleanup;
    }
  indx += len;
  msg_data_count += len;

  /* ipmi_msg_len done after message length is computed */
  ipmi_msg_len = msg_data_count;
  memcpy (ipmi_msg_len_ptr,
          &ipmi_msg_len,
          sizeof (ipmi_msg_len));

  /* Auth code must be done last, some authentication like md2 and md5
   * require all fields, including checksums, to be calculated
   * beforehand
   */
  if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE)
    {
      int authentication_len;

      memset (pwbuf, '\0', IPMI_1_5_MAX_PASSWORD_LENGTH);

      if ((authentication_len = fiid_obj_field_len_bytes (obj_lan_session_hdr,
                                                          "authentication_code")) < 0)
        {
          FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
          goto cleanup;
        }

      if (authentication_len)
        {
          if (fiid_obj_get_data (obj_lan_session_hdr,
                                 "authentication_code",
                                 pwbuf,
                                 IPMI_1_5_MAX_PASSWORD_LENGTH) < 0)
            {
              FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
              goto cleanup;
            }

          memcpy (authentication_code_field_ptr,
                  pwbuf,
                  IPMI_1_5_MAX_PASSWORD_LENGTH);
        }
      else
        {
          if (authentication_code_data)
            memcpy (pwbuf,
                    authentication_code_data,
                    authentication_code_data_len);

          if (authentication_type == IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY)
            {
              memcpy (authentication_code_field_ptr,
                      pwbuf,
                      IPMI_1_5_MAX_PASSWORD_LENGTH);
            }
          else /* IPMI_AUTHENTICATION_TYPE_MD2 || IPMI_AUTHENTICATION_TYPE_MD5 */
            {
              uint8_t session_id_buf[1024];
              uint8_t session_sequence_number_buf[1024];
              int session_id_len, session_sequence_number_len;

              if ((session_id_len = fiid_obj_get_data (obj_lan_session_hdr,
                                                       "session_id",
                                                       session_id_buf,
                                                       1024)) < 0)
                {
                  FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
                  goto cleanup;
                }

              if ((session_sequence_number_len = fiid_obj_get_data (obj_lan_session_hdr,
                                                                    "session_sequence_number",
                                                                    session_sequence_number_buf,
                                                                    1024)) < 0)
                {
                  FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr);
                  goto cleanup;
                }

              if (authentication_type == IPMI_AUTHENTICATION_TYPE_MD2)
                {
                  md2_t ctx;
                  uint8_t digest[MD2_DIGEST_LENGTH];

                  assert (IPMI_1_5_MAX_PASSWORD_LENGTH == MD2_DIGEST_LENGTH);

                  md2_init (&ctx);
                  md2_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  md2_update_data (&ctx, session_id_buf, session_id_len);
                  md2_update_data (&ctx, msg_data_ptr, msg_data_count);
                  md2_update_data (&ctx, session_sequence_number_buf, session_sequence_number_len);
                  md2_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  md2_finish (&ctx, digest, MD2_DIGEST_LENGTH);
                  md2_init (&ctx);

                  memcpy (authentication_code_field_ptr, digest, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  secure_memset (digest, '\0', MD2_DIGEST_LENGTH);
                }
              else if (authentication_type == IPMI_AUTHENTICATION_TYPE_MD5)
                {
                  md5_t ctx;
                  uint8_t digest[MD5_DIGEST_LENGTH];

                  assert (IPMI_1_5_MAX_PASSWORD_LENGTH == MD5_DIGEST_LENGTH);

                  md5_init (&ctx);
                  md5_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  md5_update_data (&ctx, session_id_buf, session_id_len);
                  md5_update_data (&ctx, msg_data_ptr, msg_data_count);
                  md5_update_data (&ctx, session_sequence_number_buf, session_sequence_number_len);
                  md5_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  md5_finish (&ctx, digest, MD5_DIGEST_LENGTH);
                  md5_init (&ctx);

                  memcpy (authentication_code_field_ptr, digest, IPMI_1_5_MAX_PASSWORD_LENGTH);
                  secure_memset (digest, '\0', MD5_DIGEST_LENGTH);
                }
            }
        }
    }

  if (indx > INT_MAX)
    {
      SET_ERRNO (EMSGSIZE);
      goto cleanup;
    }

  rv = indx;
 cleanup:
  if (rv < 0)
    secure_memset (pkt, '\0', pkt_len);
  fiid_obj_destroy (obj_lan_msg_trlr);
  secure_memset (pwbuf, '\0', IPMI_1_5_MAX_PASSWORD_LENGTH);
  return (rv);
}