openssl3.2 - 官方demo学习 - mac - gmac.c

文章目录

    • [openssl3.2 - 官方demo学习 - mac - gmac.c](#openssl3.2 - 官方demo学习 - mac - gmac.c)
    • 概述
    • 笔记
    • END

openssl3.2 - 官方demo学习 - mac - gmac.c

概述

使用GMAC算法, 设置参数(指定加密算法 e.g. AES-128-GCM, 设置iv)

用key执行初始化, 然后对明文生成MAC数据

官方注释给出建议, key, iv最好不要硬编码出现在程序中

笔记

c 复制代码
/*!
\file gmac.c
\note openssl3.2 - 官方demo学习 - mac - gmac.c
使用GMAC算法, 设置参数(指定加密算法 e.g. AES-128-GCM, 设置iv)
用key执行初始化, 然后对明文生成MAC数据
*/

/*
 * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdio.h>
#include <stdlib.h>
#include <openssl/core_names.h>
#include <openssl/evp.h>
#include <openssl/params.h>
#include <openssl/err.h>

#include "my_openSSL_lib.h"

 /*
  * Taken from NIST's GCM Test Vectors
  * http://csrc.nist.gov/groups/STM/cavp/
  */

  /*
   * Hard coding the key into an application is very bad.
   * It is done here solely for educational purposes.
   */
static unsigned char key[] = {
	0x77, 0xbe, 0x63, 0x70, 0x89, 0x71, 0xc4, 0xe2,
	0x40, 0xd1, 0xcb, 0x79, 0xe8, 0xd7, 0x7f, 0xeb
};

/*
 * The initialisation vector (IV) is better not being hard coded too.
 * Repeating password/IV pairs compromises the integrity of GMAC.
 * The IV is not considered secret information and is safe to store with
 * an encrypted password.
 */
static unsigned char iv[] = {
	0xe0, 0xe0, 0x0f, 0x19, 0xfe, 0xd7, 0xba,
	0x01, 0x36, 0xa7, 0x97, 0xf3
};

static unsigned char data[] = {
	0x7a, 0x43, 0xec, 0x1d, 0x9c, 0x0a, 0x5a, 0x78,
	0xa0, 0xb1, 0x65, 0x33, 0xa6, 0x21, 0x3c, 0xab
};

static const unsigned char expected_output[] = {
	0x20, 0x9f, 0xcc, 0x8d, 0x36, 0x75, 0xed, 0x93,
	0x8e, 0x9c, 0x71, 0x66, 0x70, 0x9d, 0xd9, 0x46
};

/*
 * A property query used for selecting the GMAC implementation and the
 * underlying GCM mode cipher.
 */
static char* propq = NULL;

int main(int argc, char** argv)
{
	int ret = EXIT_FAILURE;
	EVP_MAC* _evp_mac = NULL;
	EVP_MAC_CTX* _evp_mac_ctx = NULL;
	unsigned char out[16];
	OSSL_PARAM _ossl_param_ary[4], * p_ossl_param = _ossl_param_ary;
	OSSL_LIB_CTX* _ossl_lib_ctx = NULL;
	size_t out_len = 0;

	_ossl_lib_ctx = OSSL_LIB_CTX_new();
	if (_ossl_lib_ctx == NULL) {
		fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");
		goto end;
	}

	/* Fetch the GMAC implementation */
	_evp_mac = EVP_MAC_fetch(_ossl_lib_ctx, "GMAC", propq);
	if (_evp_mac == NULL) {
		fprintf(stderr, "EVP_MAC_fetch() returned NULL\n");
		goto end;
	}

	/* Create a context for the GMAC operation */
	_evp_mac_ctx = EVP_MAC_CTX_new(_evp_mac);
	if (_evp_mac_ctx == NULL) {
		fprintf(stderr, "EVP_MAC_CTX_new() returned NULL\n");
		goto end;
	}

	/* GMAC requires a GCM mode cipher to be specified */
	*p_ossl_param++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
		"AES-128-GCM", 0);

	/*
	 * If a non-default property query is required when fetching the GCM mode
	 * cipher, it needs to be specified too.
	 */
	if (propq != NULL)
		*p_ossl_param++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES,
			propq, 0);

	/* Set the initialisation vector (IV) */
	*p_ossl_param++ = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_IV,
		iv, sizeof(iv));
	*p_ossl_param = OSSL_PARAM_construct_end();

	/* Initialise the GMAC operation */
	if (!EVP_MAC_init(_evp_mac_ctx, key, sizeof(key), _ossl_param_ary)) {
		fprintf(stderr, "EVP_MAC_init() failed\n");
		goto end;
	}

	/* Make one or more calls to process the data to be authenticated */
	if (!EVP_MAC_update(_evp_mac_ctx, data, sizeof(data))) {
		fprintf(stderr, "EVP_MAC_update() failed\n");
		goto end;
	}

	/* Make one call to the final to get the MAC */
	if (!EVP_MAC_final(_evp_mac_ctx, out, &out_len, sizeof(out))) {
		fprintf(stderr, "EVP_MAC_final() failed\n");
		goto end;
	}

	printf("Generated MAC:\n");
	BIO_dump_indent_fp(stdout, out, (int)out_len, 2);
	putchar('\n');

	if (out_len != sizeof(expected_output)) {
		fprintf(stderr, "Generated MAC has an unexpected length\n");
		goto end;
	}

	if (CRYPTO_memcmp(expected_output, out, sizeof(expected_output)) != 0) {
		fprintf(stderr, "Generated MAC does not match expected value\n");
		goto end;
	}

	ret = EXIT_SUCCESS;
end:
	EVP_MAC_CTX_free(_evp_mac_ctx);
	EVP_MAC_free(_evp_mac);
	OSSL_LIB_CTX_free(_ossl_lib_ctx);
	if (ret != EXIT_SUCCESS)
		ERR_print_errors_fp(stderr);
	return ret;
}

END

相关推荐
coder4_11 天前
OpenSSL 加密算法与证书管理全解析:从基础到私有 CA 实战
https·openssl·ssl/tls·加密算法·ca证书
王小义笔记18 天前
windows电脑如何执行openssl rand命令
windows·openssl
Humbunklung21 天前
VC++ 使用OpenSSL创建RSA密钥PEM文件
开发语言·c++·openssl
深耕AI2 个月前
Win64OpenSSL-3_5_2.exe【安装步骤】
openssl
看那山瞧那水2 个月前
DELPHI 利用OpenSSL实现加解密,证书(X.509)等功能
delphi·openssl
洋哥网络科技2 个月前
openssl升级
openssl
Lazy Dave2 个月前
gmssl私钥文件格式
网络安全·ssl·openssl
沉在嵌入式的鱼3 个月前
RK3588移植Openssl库
linux·rk3588·openssl
黑屋里的马3 个月前
ssl相关命令生成证书
服务器·网络·ssl·openssl·gmssl
fangeqin4 个月前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl