Example #1
0
static int
int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
	if (!CMAC_Update(ctx->pctx->data, data, count))
		return 0;
	return 1;
}
Example #2
0
static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out,
		unsigned char *Key, int Klen,
		unsigned char *Msg, int Mlen,
		int Tlen)
	{
	int rc, i;
	size_t reslen;
	unsigned char res[128];
	CMAC_CTX *cmac_ctx = CMAC_CTX_new();

	CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
	CMAC_Update(cmac_ctx, Msg, Mlen);
	if (!CMAC_Final(cmac_ctx, res, &reslen))
		{
		fputs("Error calculating CMAC\n", stderr);
		rc = 0;
		}
	else if (Tlen > (int)reslen)
		{
		fputs("Parameter error, Tlen > CMAC length\n", stderr);
		rc = 0;
		}
	else
		{
		fputs("Mac = ", out);
		for (i = 0; i < Tlen; i++)
			fprintf(out, "%02x", res[i]);
		fputs("\n", out);
		rc = 1;
		}
	CMAC_CTX_free(cmac_ctx);
	return rc;
	}
Example #3
0
sgx_status_t sgx_cmac128_msg(const sgx_key_128bit_t key, const uint8_t *p_src, unsigned int src_len, sgx_mac_t *p_mac)
{
    if(!key || !p_src || src_len == 0 || !p_mac)
    {
        return SGX_ERROR_INVALID_PARAMETER;
    }
    CMAC_CTX *cmac_ctx = NULL;
    size_t mac_len;
    
    if(!(cmac_ctx = CMAC_CTX_new()))
    {
        return SGX_ERROR_OUT_OF_MEMORY;
    }
    if(!CMAC_Init(cmac_ctx, key, sizeof(sgx_key_128bit_t), EVP_aes_128_cbc(), NULL))
    {
        CMAC_CTX_free(cmac_ctx);
        return SGX_ERROR_UNEXPECTED;
    }
    if(!CMAC_Update(cmac_ctx, p_src, src_len))
    {
        CMAC_CTX_free(cmac_ctx);
        return SGX_ERROR_UNEXPECTED;
    }
       if(!CMAC_Final(cmac_ctx, (uint8_t *)p_mac, &mac_len))
    {
        CMAC_CTX_free(cmac_ctx);
        return SGX_ERROR_UNEXPECTED;
    }
    CMAC_CTX_free(cmac_ctx);
    assert(mac_len == sizeof(sgx_mac_t));
    return SGX_SUCCESS;    

}
Example #4
0
BUF_MEM *
cmac(CMAC_CTX *ctx, const EVP_CIPHER *type, const BUF_MEM * key,
        const BUF_MEM * in, size_t maclen)
{
    CMAC_CTX * cmac_ctx = NULL;
    BUF_MEM * out = NULL, * tmp = NULL;
    size_t cmac_len = 0;

    check((key && in && type), "Invalid arguments");

    check((key->length >= (size_t) EVP_CIPHER_key_length(type)),
            "Key is too short");

    if (ctx)
        cmac_ctx = ctx;
    else {
        cmac_ctx = CMAC_CTX_new();
    }

    /* Initialize the CMAC context, feed in the data, and get the required
     * output buffer size */
    if (!cmac_ctx ||
            !CMAC_Init(cmac_ctx, key->data, EVP_CIPHER_key_length(type),
                type, NULL) ||
            !CMAC_Update(cmac_ctx, in->data, in->length) ||
            !CMAC_Final(cmac_ctx, NULL, &cmac_len))
        goto err;

    /* get buffer in required size */
    out = BUF_MEM_create(cmac_len);
    if (!out)
        goto err;

    /* get the actual CMAC */
    if (!CMAC_Final(cmac_ctx, (unsigned char*) out->data, &out->length))
        goto err;

    /* Truncate the CMAC if necessary */
    if (cmac_len > maclen) {
        tmp = BUF_MEM_create_init(out->data, maclen);
        BUF_MEM_free(out);
        out = tmp;
    }

    if (!ctx)
        CMAC_CTX_free(cmac_ctx);

    return out;

err:
    if (cmac_ctx && !ctx) {
        CMAC_CTX_free(cmac_ctx);
    }
    if (out) {
        BUF_MEM_free(out);
    }

    return NULL;
}
Example #5
0
/* 7.3.45 */
int SAF_MacUpdate(
	void *hKeyHandle,
	const unsigned char *pucInData,
	unsigned int uiInDataLen)
{
	int ret = SAR_UnknownErr;
	SAF_KEY *hkey = (SAF_KEY *)hKeyHandle;

	if (!hKeyHandle || !pucInData) {
		SAFerr(SAF_F_SAF_MACUPDATE, ERR_R_PASSED_NULL_PARAMETER);
		return SAR_IndataErr;
	}

	if (uiInDataLen <= 0 || uiInDataLen > INT_MAX) {
		SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_INVALID_INPUT_LENGTH);
		return SAR_IndataLenErr;
	}

	if (!hkey->cmac_ctx) {
		const EVP_CIPHER *cipher;

		if (!(cipher = EVP_get_cipherbysgd(hkey->hSymmKeyObj->uiCryptoAlgID))) {
			SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_INVALID_KEY_HANDLE);
			ret = SAR_IndataErr;
			goto end;
		}

		if (!(hkey->cmac_ctx = CMAC_CTX_new())) {
			SAFerr(SAF_F_SAF_MACUPDATE, ERR_R_MALLOC_FAILURE);
			goto end;
		}

		if (!CMAC_Init(hkey->cmac_ctx, hkey->key, hkey->keylen, cipher,
			hkey->hSymmKeyObj->app->engine)) {
			SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_CMAC_FAILURE);
			goto end;
		}
	}

	if (!CMAC_Update(hkey->cmac_ctx, pucInData, uiInDataLen)) {
		SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_CMAC_FAILURE);
		return SAR_UnknownErr;
	}

	ret = SAR_OK;

end:
	if (ret != SAR_OK && hkey->cmac_ctx) {
		CMAC_CTX_free(hkey->cmac_ctx);
		hkey->cmac_ctx = NULL;
	}
	return ret;
}
Example #6
0
/* CMAC-AES256: generate hash of known digest value and compare to known
   precomputed correct hash
*/
static int FIPS_cmac_aes256_test()
{
    unsigned char key[] = { 0x60,0x3d,0xeb,0x10, 0x15,0xca,0x71,0xbe,
                            0x2b,0x73,0xae,0xf0, 0x85,0x7d,0x77,0x81,
                            0x1f,0x35,0x2c,0x07, 0x3b,0x61,0x08,0xd7,
                            0x2d,0x98,0x10,0xa3, 0x09,0x14,0xdf,0xf4,
                          };
    unsigned char data[] = "Sample text";
    unsigned char kaval[] =
    {   0xec,0xc2,0xcf,0x63, 0xc7,0xce,0xfc,0xa4,
        0xb0,0x86,0x37,0x5f, 0x15,0x60,0xba,0x1f,
    };

    unsigned char *out = NULL;
    size_t outlen;
    CMAC_CTX *ctx = CMAC_CTX_new();
    int r = 0;

    ERR_clear_error();

    if (!ctx)
        goto end;
    if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_256_cbc(),NULL))
        goto end;
    if (!CMAC_Update(ctx,data,sizeof(data)-1))
        goto end;
    /* This should return 1.  If not, there's a programming error... */
    if (!CMAC_Final(ctx, out, &outlen))
        goto end;
    out = OPENSSL_malloc(outlen);
    if (!CMAC_Final(ctx, out, &outlen))
        goto end;
#if 0
    {
        char *hexout = OPENSSL_malloc(outlen * 2 + 1);
        bin2hex(out, outlen, hexout);
        printf("CMAC-AES256: res = %s\n", hexout);
        OPENSSL_free(hexout);
    }
    r = 1;
#else
    if (!memcmp(out,kaval,outlen))
        r = 1;
#endif
end:
    CMAC_CTX_free(ctx);
    if (out)
        OPENSSL_free(out);
    return r;
}
Example #7
0
/* CMAC-AES192: generate hash of known digest value and compare to known
   precomputed correct hash
*/
static int FIPS_cmac_aes192_test()
{
    unsigned char key[] = { 0x8e,0x73,0xb0,0xf7, 0xda,0x0e,0x64,0x52,
                            0xc8,0x10,0xf3,0x2b, 0x80,0x90,0x79,0xe5,
                            0x62,0xf8,0xea,0xd2, 0x52,0x2c,0x6b,0x7b,
                          };
    unsigned char data[] = "Sample text";
    unsigned char kaval[] =
    {   0xd6,0x99,0x19,0x25, 0xe5,0x1d,0x95,0x48,
        0xb1,0x4a,0x0b,0xf2, 0xc6,0x3c,0x47,0x1f,
    };

    unsigned char *out = NULL;
    size_t outlen;
    CMAC_CTX *ctx = CMAC_CTX_new();
    int r = 0;

    ERR_clear_error();

    if (!ctx)
        goto end;
    if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_192_cbc(),NULL))
        goto end;
    if (!CMAC_Update(ctx,data,sizeof(data)-1))
        goto end;
    /* This should return 1.  If not, there's a programming error... */
    if (!CMAC_Final(ctx, out, &outlen))
        goto end;
    out = OPENSSL_malloc(outlen);
    if (!CMAC_Final(ctx, out, &outlen))
        goto end;
#if 0
    {
        char *hexout = OPENSSL_malloc(outlen * 2 + 1);
        bin2hex(out, outlen, hexout);
        printf("CMAC-AES192: res = %s\n", hexout);
        OPENSSL_free(hexout);
    }
    r = 1;
#else
    if (!memcmp(out,kaval,outlen))
        r = 1;
#endif
end:
    CMAC_CTX_free(ctx);
    if (out)
        OPENSSL_free(out);
    return r;
}
Example #8
0
/* CMAC-AES128: generate hash of known digest value and compare to known
   precomputed correct hash
*/
static int FIPS_cmac_aes128_test()
{
    unsigned char key[16] = { 0x2b,0x7e,0x15,0x16, 0x28,0xae,0xd2,0xa6,
                              0xab,0xf7,0x15,0x88, 0x09,0xcf,0x4f,0x3c,
                            };
    unsigned char data[] = "Sample text";
    unsigned char kaval[EVP_MAX_MD_SIZE] =
    {   0x16,0x83,0xfe,0xac, 0x52,0x9b,0xae,0x23,
        0xd7,0xd5,0x66,0xf5, 0xd2,0x8d,0xbd,0x2a,
    };

    unsigned char *out = NULL;
    size_t outlen;
    CMAC_CTX *ctx = CMAC_CTX_new();
    int r = 0;

    ERR_clear_error();

    if (!ctx)
        goto end;
    if (!CMAC_Init(ctx,key,sizeof(key),EVP_aes_128_cbc(),NULL))
        goto end;
    if (!CMAC_Update(ctx,data,sizeof(data)-1))
        goto end;
    /* This should return 1.  If not, there's a programming error... */
    if (!CMAC_Final(ctx, out, &outlen))
        goto end;
    out = OPENSSL_malloc(outlen);
    if (!CMAC_Final(ctx, out, &outlen))
        goto end;
#if 0
    {
        char *hexout = OPENSSL_malloc(outlen * 2 + 1);
        bin2hex(out, outlen, hexout);
        printf("CMAC-AES128: res = %s\n", hexout);
        OPENSSL_free(hexout);
    }
    r = 1;
#else
    if (!memcmp(out,kaval,outlen))
        r = 1;
#endif
end:
    CMAC_CTX_free(ctx);
    if (out)
        OPENSSL_free(out);
    return r;
}
Example #9
0
/* CMAC-TDEA3: generate hash of known digest value and compare to known
   precomputed correct hash
*/
static int FIPS_cmac_tdea3_test()
{
    unsigned char key[] = { 0x8a,0xa8,0x3b,0xf8, 0xcb,0xda,0x10,0x62,
                            0x0b,0xc1,0xbf,0x19, 0xfb,0xb6,0xcd,0x58,
                            0xbc,0x31,0x3d,0x4a, 0x37,0x1c,0xa8,0xb5,
                          };
    unsigned char data[] = "Sample text";
    unsigned char kaval[EVP_MAX_MD_SIZE] =
    { 0xb4,0x06,0x4e,0xbf, 0x59,0x89,0xba,0x68, };

    unsigned char *out = NULL;
    size_t outlen;
    CMAC_CTX *ctx = CMAC_CTX_new();
    int r = 0;

    ERR_clear_error();

    if (!ctx)
        goto end;
    if (!CMAC_Init(ctx,key,sizeof(key),EVP_des_ede3_cbc(),NULL))
        goto end;
    if (!CMAC_Update(ctx,data,sizeof(data)-1))
        goto end;
    /* This should return 1.  If not, there's a programming error... */
    if (!CMAC_Final(ctx, out, &outlen))
        goto end;
    out = OPENSSL_malloc(outlen);
    if (!CMAC_Final(ctx, out, &outlen))
        goto end;
#if 0
    {
        char *hexout = OPENSSL_malloc(outlen * 2 + 1);
        bin2hex(out, outlen, hexout);
        printf("CMAC-TDEA3: res = %s\n", hexout);
        OPENSSL_free(hexout);
    }
    r = 1;
#else
    if (!memcmp(out,kaval,outlen))
        r = 1;
#endif
end:
    CMAC_CTX_free(ctx);
    if (out)
        OPENSSL_free(out);
    return r;
}
int FIPS_selftest_cmac()
{
    size_t n, outlen;
    unsigned char out[32];
    const EVP_CIPHER *cipher;
    CMAC_CTX *ctx = CMAC_CTX_new();
    const CMAC_KAT *t;
    int rv = 1;

    for (n = 0, t = vector; n < sizeof(vector) / sizeof(vector[0]); n++, t++) {
        cipher = FIPS_get_cipherbynid(t->nid);
        if (!cipher) {
            rv = -1;
            goto err;
        }
        if (!CMAC_Init(ctx, t->key, t->keysize / 8, cipher, 0)) {
            rv = -1;
            goto err;
        }
        if (!CMAC_Update(ctx, t->msg, t->msgsize / 8)) {
            rv = -1;
            goto err;
        }

        if (!CMAC_Final(ctx, out, &outlen)) {
            rv = -1;
            goto err;
        }
        CMAC_CTX_cleanup(ctx);

        if (outlen < t->macsize / 8 || memcmp(out, t->mac, t->macsize / 8)) {
            rv = 0;
        }
    }

 err:
    CMAC_CTX_free(ctx);

    if (rv == -1) {
        rv = 0;
    }
    if (!rv)
        FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC, FIPS_R_SELFTEST_FAILED);

    return rv;
}
Example #11
0
//  We are doing CBC-MAC not CMAC at this time
bool AES_CMAC_Validate(COSE_MacMessage * pcose, int KeySize, int TagSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
{
	CMAC_CTX * pctx = NULL;
	const EVP_CIPHER * pcipher = NULL;
	byte * rgbOut = NULL;
	size_t cbOut;
	bool f = false;
	unsigned int i;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pcose->m_message.m_allocContext;
#endif

	pctx = CMAC_CTX_new();


	switch (KeySize) {
	case 128: pcipher = EVP_aes_128_cbc(); break;
	case 256: pcipher = EVP_aes_256_cbc(); break;
	default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break;
	}

	rgbOut = COSE_CALLOC(128/8, 1, context);
	CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(CMAC_Init(pctx, pcose->pbKey, pcose->cbKey, pcipher, NULL /*impl*/) == 1, COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(CMAC_Update(pctx, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);
	CHECK_CONDITION(CMAC_Final(pctx, rgbOut, &cbOut), COSE_ERR_CRYPTO_FAIL);

	cn_cbor * cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
	CHECK_CONDITION(cn != NULL, COSE_ERR_CBOR);

	for (i = 0; i < (unsigned int)TagSize / 8; i++) f |= (cn->v.bytes[i] != rgbOut[i]);

	COSE_FREE(rgbOut, context);
	CMAC_CTX_cleanup(pctx);
	CMAC_CTX_free(pctx);
	return !f;

errorReturn:
	COSE_FREE(rgbOut, context);
	CMAC_CTX_cleanup(pctx);
	CMAC_CTX_free(pctx);
	return false;

}
Example #12
0
/*
 * Calculate per-link MAC by pathname
 */
static int32_t calc_link_mac_v1(struct mtd_format_v1 *fmt,
				loc_t *loc,
				unsigned char *result,
				struct crypt_inode_info *info,
				struct master_cipher_info *master)
{
	int32_t ret;	
	unsigned char nmtd_link_key[16];
	CMAC_CTX *cctx;
	size_t len;

	ret = get_nmtd_link_key(loc, master, nmtd_link_key);
	if (ret) {
		gf_log("crypt", GF_LOG_ERROR, "Can not get nmtd link key");
		return -1;
	}
	cctx = CMAC_CTX_new();
	if (!cctx) {
		gf_log("crypt", GF_LOG_ERROR, "CMAC_CTX_new failed");
		return -1; 
	}
	ret = CMAC_Init(cctx, nmtd_link_key, sizeof(nmtd_link_key),
			EVP_aes_128_cbc(), 0);
	if (!ret) {
		gf_log("crypt", GF_LOG_ERROR, "CMAC_Init failed");
		CMAC_CTX_free(cctx);
		return -1;
	}
	ret = CMAC_Update(cctx, get_NMTD_V1(info), SIZE_OF_NMTD_V1);
	if (!ret) {
		gf_log("crypt", GF_LOG_ERROR, "CMAC_Update failed");
		CMAC_CTX_free(cctx);
		return -1;
	}
	ret = CMAC_Final(cctx, result, &len);
	CMAC_CTX_free(cctx);
	if (!ret) {
		gf_log("crypt", GF_LOG_ERROR, "CMAC_Final failed");
		return -1;
	}
	return 0;
}
Example #13
0
static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out,
		unsigned char *Key, int Klen,
		unsigned char *Msg, int Mlen,
		unsigned char *Mac, int Maclen,
		int Tlen)
	{
	int rc;
	size_t reslen;
	unsigned char res[128];
	CMAC_CTX *cmac_ctx = CMAC_CTX_new();

	CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
	CMAC_Update(cmac_ctx, Msg, Mlen);
	if (!CMAC_Final(cmac_ctx, res, &reslen))
		{
		fputs("Error calculating CMAC\n", stderr);
		rc = 0;
		}
	else if (Tlen > (int)reslen)
		{
		fputs("Parameter error, Tlen > CMAC length\n", stderr);
		rc = 0;
		}
	else if (Tlen != Maclen)
		{
		fputs("Parameter error, Tlen != resulting Mac length\n", stderr);
		rc = 0;
		}
	else
		{
		if (!memcmp(Mac, res, Maclen))
			fputs("Result = P\n", out);
		else
			fputs("Result = F\n", out);
		}
	CMAC_CTX_free(cmac_ctx);
	return rc;
	}
static
  void
test_cmac (
  const uint8_t * key,
  unsigned key_length,
  const uint8_t * message,
  unsigned length,
  const uint8_t * expect,
  unsigned expected_length)
{
  size_t                                  size;
  uint8_t                                 result[16];

  ctx = CMAC_CTX_new ();
  CMAC_Init (ctx, key, key_length, EVP_aes_128_cbc (), NULL);
  CMAC_Update (ctx, message, length);
  CMAC_Final (ctx, result, &size);
  CMAC_CTX_free (ctx);

  if (compare_buffer (result, size, expect, expected_length) != 0) {
    fail ("test_cmac");
  }
}
Example #15
0
int FIPS_selftest_cmac()
	{
	size_t n, outlen;
	unsigned char    out[32];
	const EVP_CIPHER *cipher;
	CMAC_CTX *ctx = CMAC_CTX_new();
	const CMAC_KAT *t;
	int subid = -1, rv = 1;

	for(n=0,t=vector; n<sizeof(vector)/sizeof(vector[0]); n++,t++)
		{
		cipher = FIPS_get_cipherbynid(t->nid);
		if (!cipher)
			{
			rv = -1;
			goto err;
			}
		subid = M_EVP_CIPHER_nid(cipher);
		if (!fips_post_started(FIPS_TEST_CMAC, subid, 0))
			continue;
		if (!CMAC_Init(ctx, t->key, t->keysize/8, cipher, 0))
			{
			rv = -1;
			goto err;
			}
		if (!CMAC_Update(ctx, t->msg, t->msgsize/8))
			{
			rv = -1;
			goto err;
			}
			
		if (!fips_post_corrupt(FIPS_TEST_CMAC, subid, NULL))
			{
			if (!CMAC_Update(ctx, t->msg, 1))
				{
				rv = -1;
				goto err;
				}
			}
		if (!CMAC_Final(ctx, out, &outlen))
			{
			rv = -1;
			goto err;
			}
		CMAC_CTX_cleanup(ctx);

		if(outlen < t->macsize/8 || memcmp(out,t->mac,t->macsize/8))
			{
			fips_post_failed(FIPS_TEST_CMAC, subid, NULL);
		    	rv = 0;
		    	}
		else if (!fips_post_success(FIPS_TEST_CMAC, subid, NULL))
			{
			rv = 0;
			goto err;
			}
		}

	err:
	CMAC_CTX_free(ctx);

	if (rv == -1)
		{
		fips_post_failed(FIPS_TEST_CMAC, subid, NULL);
		rv = 0;
		}
	if (!rv)
		   FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC,FIPS_R_SELFTEST_FAILED);

	return rv;
	}
Example #16
0
int OTP_generate(const OTP_PARAMS *params, const void *event, size_t eventlen,
	unsigned int *otp, const unsigned char *key, size_t keylen)
{
	int ret = 0;
	time_t t = 0;
	unsigned char *id = NULL;
	size_t idlen;
	const EVP_MD *md;
	const EVP_CIPHER *cipher;
	EVP_MD_CTX *mdctx = NULL;
	CMAC_CTX *cmctx = NULL;
	unsigned char s[EVP_MAX_MD_SIZE];
	size_t slen;
	uint32_t od;
	int i, n;

	OPENSSL_assert(sizeof(time_t) == 8);

	if (!check_params(params)) {
		OTPerr(OTP_F_OTP_GENERATE, OTP_R_INVALID_PARAMS);
		return 0;
	}

	idlen = sizeof(uint64_t) + eventlen + params->option_size;
	if (idlen < 16) {
		idlen = 16;
	}
	if (!(id = OPENSSL_malloc(idlen))) {
		OTPerr(OTP_F_OTP_GENERATE, ERR_R_MALLOC_FAILURE);
		goto end;
	}
	memset(id, 0, idlen);

	t = time(NULL) + params->offset;
	t /= params->te;

	memcpy(id, &t, sizeof(t));
	memcpy(id + sizeof(t), event, eventlen);
	memcpy(id + sizeof(t) + eventlen, params->option, params->option_size);


	/* FIXME: try to get md and cipher, and check if cipher is ECB */
	if (params->type == NID_sm3) {
		md = EVP_get_digestbynid(params->type);
		if (!(mdctx = EVP_MD_CTX_new())) {
			OTPerr(OTP_F_OTP_GENERATE, ERR_R_MALLOC_FAILURE);
			goto end;
		}
		if (!EVP_DigestInit_ex(mdctx, md, NULL)) {
			OTPerr(OTP_F_OTP_GENERATE, ERR_R_EVP_LIB);
			goto end;
		}
		if (!EVP_DigestUpdate(mdctx, key, keylen)) {
			OTPerr(OTP_F_OTP_GENERATE, ERR_R_EVP_LIB);
			goto end;
		}
		if (!EVP_DigestUpdate(mdctx, id, idlen)) {
			OTPerr(OTP_F_OTP_GENERATE, ERR_R_EVP_LIB);
			goto end;
		}
		if (!EVP_DigestFinal_ex(mdctx, s, (unsigned int *)&slen)) {
			OTPerr(OTP_F_OTP_GENERATE, ERR_R_EVP_LIB);
			goto end;
		}
	} else if (params->type == NID_sms4_ecb) {
		cipher = EVP_get_cipherbynid(params->type);
		if (!(cmctx = CMAC_CTX_new())) {
			OTPerr(OTP_F_OTP_GENERATE, ERR_R_MALLOC_FAILURE);
			goto end;
		}
		if (!CMAC_Init(cmctx, key, keylen, cipher, NULL)) {
			OTPerr(OTP_F_OTP_GENERATE, OTP_R_CMAC_FAILURE);
			goto end;
		}
		if (!CMAC_Update(cmctx, id, idlen)) {
			OTPerr(OTP_F_OTP_GENERATE, OTP_R_CMAC_FAILURE);
			goto end;
		}
		if (!CMAC_Final(cmctx, s, &slen)) {
			OTPerr(OTP_F_OTP_GENERATE, OTP_R_CMAC_FAILURE);
			goto end;
		}
	} else {
		goto end;
	}
	OPENSSL_assert(slen % 4 == 0);

	od = 0;

	n = (int)slen;
	for (i = 0; i < n/4; i++) {
		od += GETU32(&s[i * 4]);
	}

	*otp = od % pow_table[params->otp_digits];
	ret = 1;
end:
	OPENSSL_free(id);
	EVP_MD_CTX_free(mdctx);
	CMAC_CTX_free(cmctx);
	return ret;
}
/*!
   @brief Create integrity cmac t for a given message.
   @param[in] stream_cipher Structure containing various variables to setup encoding
   @param[out] out For EIA2 the output string is 32 bits long
*/
int
nas_stream_encrypt_eia2 (
  nas_stream_cipher_t * stream_cipher,
  uint8_t out[4])
{
  uint8_t                                *m = NULL;
  uint32_t                                local_count;
  size_t                                  size = 4;
  uint8_t                                 data[16];
  CMAC_CTX                               *cmac_ctx = NULL;
  const EVP_CIPHER                       *cipher = EVP_aes_128_cbc ();
  uint32_t                                zero_bit = 0;
  uint32_t                                m_length;
  int                                     ret;

  DevAssert (stream_cipher != NULL);
  DevAssert (stream_cipher->key != NULL);
  DevAssert (stream_cipher->key_length > 0);
  DevAssert (out != NULL);
  memset (data, 0, 16);
  zero_bit = stream_cipher->blength & 0x7;
  m_length = stream_cipher->blength >> 3;

  if (zero_bit > 0)
    m_length += 1;

  local_count = hton_int32 (stream_cipher->count);
  m = calloc (m_length + 8, sizeof (uint8_t));
  memcpy (&m[0], &local_count, 4);
  m[4] = ((stream_cipher->bearer & 0x1F) << 3) | ((stream_cipher->direction & 0x01) << 2);
  memcpy (&m[8], stream_cipher->message, m_length);
#if SECU_DEBUG
  {
    int                                     i;

    printf ("Byte length: %u, Zero bits: %u\nm: ", m_length + 8, zero_bit);

    for (i = 0; i < m_length + 8; i++)
      printf ("%02x", m[i]);

    printf ("\nKey:");

    for (i = 0; i < stream_cipher->key_length; i++)
      printf ("%02x", stream_cipher->key[i]);

    printf ("\nMessage:");

    for (i = 0; i < m_length; i++)
      printf ("%02x", stream_cipher->message[i]);

    printf ("\n");
  }
#endif
  cmac_ctx = CMAC_CTX_new ();
  ret = CMAC_Init (cmac_ctx, stream_cipher->key, stream_cipher->key_length, cipher, NULL);
  ret = CMAC_Update (cmac_ctx, m, m_length + 8);
  CMAC_Final (cmac_ctx, data, &size);
  CMAC_CTX_free (cmac_ctx);
#if SECU_DEBUG
  {
    int                                     i;

    printf ("out: ");

    for (i = 0; i < size; i++)
      printf ("%02x", data[i]);

    printf ("\n");
  }
#endif
  memcpy (out, data, 4);
  free (m);
  return 0;
}