[][openwrt][mt7988][fips][Develop gcm ccm tools]

[Description]
Add gcm ccm tools based on openssl api.
This tools is for CAVP test.

[Release-log]
N/A

Change-Id: I4363fa7a2f2d1a75c4c3ee4f445912b0551dc81d
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7512445
diff --git a/feed/openssl-fips-ext/src/aesccm.c b/feed/openssl-fips-ext/src/aesccm.c
new file mode 100644
index 0000000..2d8bf69
--- /dev/null
+++ b/feed/openssl-fips-ext/src/aesccm.c
@@ -0,0 +1,140 @@
+#include "aesccm.h"
+
+
+struct operator ccm_oper = {
+	.init = ccm_init,
+	.uninit = ccm_uninit,
+	.encrypt = ccm_encrypt,
+	.decrypt = ccm_decrypt,
+	.check = ccm_check,
+};
+
+static struct ccm_data data;
+
+int ccm_init(void)
+{
+	hex2bin(&data.key, input_data.key, &(data.key_size));
+	hex2bin(&data.nonce, input_data.nonce, &(data.nonce_size));
+	hex2bin(&data.adata, input_data.adata, &(data.adata_size));
+	hex2bin(&data.payload, input_data.payload, &(data.payload_size));
+	hex2bin(&data.ct, input_data.ct, &(data.ct_size));
+	if (input_data.oper == DECRYPT) {
+		hex2bin(&data.tag, input_data.tag, &(data.tag_size));
+	} else if (input_data.oper == ENCRYPT) {
+		if (input_data.tag != NULL)
+			data.tag_size = atoi(input_data.tag);
+		else
+			data.tag_size = 16;
+	}
+	return 0;
+}
+
+void init_ccm_evp_encrypt(EVP_CIPHER_CTX **ctx)
+{
+	if (data.key_size == 16)
+		EVP_EncryptInit_ex(*ctx, EVP_aes_128_ccm(), NULL, NULL, NULL);
+	else if (data.key_size == 24)
+		EVP_EncryptInit_ex(*ctx, EVP_aes_192_ccm(), NULL, NULL, NULL);
+	else if (data.key_size == 32)
+		EVP_EncryptInit_ex(*ctx, EVP_aes_256_ccm(), NULL, NULL, NULL);
+}
+
+void init_ccm_evp_decrypt(EVP_CIPHER_CTX **ctx)
+{
+	if (data.key_size == 16)
+		EVP_DecryptInit_ex(*ctx, EVP_aes_128_ccm(), NULL, NULL, NULL);
+	else if (data.key_size == 24)
+		EVP_DecryptInit_ex(*ctx, EVP_aes_192_ccm(), NULL, NULL, NULL);
+	else if (data.key_size == 32)
+		EVP_DecryptInit_ex(*ctx, EVP_aes_256_ccm(), NULL, NULL, NULL);
+}
+int ccm_encrypt(void)
+{
+	EVP_CIPHER_CTX *ctx;
+	int outlen;
+	unsigned char outbuf[1024];
+
+	ctx = EVP_CIPHER_CTX_new();
+	init_ccm_evp_encrypt(&ctx);
+
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, data.nonce_size, NULL);
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, data.tag_size, NULL);
+	EVP_EncryptInit_ex(ctx, NULL, NULL, data.key, data.nonce);
+
+	EVP_EncryptUpdate(ctx, NULL, &outlen, NULL, data.payload_size);
+	if (data.adata != NULL)
+		EVP_EncryptUpdate(ctx, NULL, &outlen, data.adata, data.adata_size);
+	if (data.payload != NULL) {
+		EVP_EncryptUpdate(ctx, outbuf, &outlen, data.payload, data.payload_size);
+		printf("Ciphertext: ");
+		print_hex(outbuf, outlen);
+	}
+	EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, data.tag_size, outbuf);
+	printf("Tags: ");
+	print_hex(outbuf, data.tag_size);
+	EVP_CIPHER_CTX_free(ctx);
+	return 0;
+}
+
+int ccm_decrypt(void)
+{
+	EVP_CIPHER_CTX *ctx;
+	int outlen, rv;
+	unsigned char outbuf[1024];
+
+	ctx = EVP_CIPHER_CTX_new();
+
+	init_ccm_evp_decrypt(&ctx);
+
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, data.nonce_size, NULL);
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, data.tag_size, data.tag);
+	EVP_DecryptInit_ex(ctx, NULL, NULL, data.key, data.nonce);
+	EVP_DecryptUpdate(ctx, NULL, &outlen, NULL, data.ct_size);
+
+	if (data.adata != NULL)
+		EVP_DecryptUpdate(ctx, NULL, &outlen, data.adata, data.adata_size);
+
+	if (data.ct == NULL)
+		rv = EVP_DecryptUpdate(ctx, outbuf, &outlen, "", data.ct_size);
+	else
+		rv = EVP_DecryptUpdate(ctx, outbuf, &outlen, data.ct, data.ct_size);
+
+	if (rv > 0) {
+		printf("Tag Verify: Pass\n");
+		if (data.ct != NULL) {
+			printf("Plaintext: ");
+			print_hex(outbuf, outlen);
+		}
+	} else {
+		printf("Tag Verify: Fail\n");
+	}
+
+	EVP_CIPHER_CTX_free(ctx);
+	return 0;
+}
+int ccm_uninit(void)
+{
+	free_openssl_data(data.key);
+	free_openssl_data(data.nonce);
+	free_openssl_data(data.adata);
+	free_openssl_data(data.payload);
+	free_openssl_data(data.ct);
+	free_openssl_data(data.tag);
+	return 0;
+}
+
+int ccm_check(void)
+{
+	if (data.key == NULL || data.nonce == NULL) {
+		printf("ccm must have Key and IV\n");
+		return -1;
+	}
+
+	if (input_data.oper == DECRYPT && data.tag == NULL) {
+		printf("ccm decrypt must have Tag\n");
+		return -1;
+	}
+
+	return 0;
+}