openssl3.2 - 官方demo学习 - digest - EVP_MD_xof.c

文章目录

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

openssl3.2 - 官方demo学习 - digest - EVP_MD_xof.c

概述

使用支持XOF方式的摘要算法(e.g. SHAKE256), 对buffer进行摘要, 并和预留的摘要值进行比对

笔记

c 复制代码
/*!
\file EVP_MD_xof.c
\note openssl3.2 - 官方demo学习 - digest - EVP_MD_xof.c
使用支持XOF方式的摘要算法(e.g. SHAKE256), 对buffer进行摘要, 并和预留的摘要值进行比对
*/

/*-
 * Copyright 2022-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 <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/core_names.h>

#include "my_openSSL_lib.h"

/*
 * Example of using an extendable-output hash function (XOF). A XOF is a hash
 * function with configurable output length and which can generate an
 * arbitrarily large output.
 *
 * This example uses SHAKE256, an extendable output variant of SHA3 (Keccak).
 *
 * To generate different output lengths, you can pass a single integer argument
 * on the command line, which is the output size in bytes. By default, a 20-byte
 * output is generated and (for this length only) a known answer test is
 * performed.
 */

/* Our input to the XOF hash function. */
const char message[] = "This is a test message.";

/* Expected output when an output length of 20 bytes is used. */
static const char known_answer[] = {
  0x52, 0x97, 0x93, 0x78, 0x27, 0x58, 0x7d, 0x62,
  0x8b, 0x00, 0x25, 0xb5, 0xec, 0x39, 0x5e, 0x2d,
  0x7f, 0x3e, 0xd4, 0x19
};

/*
 * A property query used for selecting the SHAKE256 implementation.
 */
static const char *propq = NULL;

int main(int argc, char **argv)
{
    int ret = EXIT_FAILURE;
    OSSL_LIB_CTX *_ossl_lib_ctx = NULL;
    EVP_MD *_evp_md = NULL;
    EVP_MD_CTX *_evp_md_ctx = NULL;
    unsigned int digest_len = 20;
    int digest_len_i;
    unsigned char *_psz_digest = NULL;

    /* Allow digest length to be changed for demonstration purposes. */
    if (argc > 1) {
        digest_len_i = atoi(argv[1]);
        if (digest_len_i <= 0) {
            fprintf(stderr, "Specify a non-negative digest length\n");
            goto end;
        }

        digest_len = (unsigned int)digest_len_i;
    }

    /*
     * Retrieve desired algorithm. This must be a hash algorithm which supports
     * XOF.
     */
    _evp_md = EVP_MD_fetch(_ossl_lib_ctx, "SHAKE256", propq);
    if (_evp_md == NULL) {
        fprintf(stderr, "Failed to retrieve SHAKE256 algorithm\n");
        goto end;
    }

    /* Create context. */
    _evp_md_ctx = EVP_MD_CTX_new();
    if (_evp_md_ctx == NULL) {
        fprintf(stderr, "Failed to create digest context\n");
        goto end;
    }

    /* Initialize digest context. */
    if (EVP_DigestInit(_evp_md_ctx, _evp_md) == 0) {
        fprintf(stderr, "Failed to initialize digest\n");
        goto end;
    }

    /*
     * Feed our message into the digest function.
     * This may be called multiple times.
     */
    if (EVP_DigestUpdate(_evp_md_ctx, message, sizeof(message)) == 0) {
        fprintf(stderr, "Failed to hash input message\n");
        goto end;
    }

    /* Allocate enough memory for our digest length. */
    _psz_digest = OPENSSL_malloc(digest_len);
    if (_psz_digest == NULL) {
        fprintf(stderr, "Failed to allocate memory for digest\n");
        goto end;
    }

    /* Get computed digest. The digest will be of whatever length we specify. */
    if (EVP_DigestFinalXOF(_evp_md_ctx, _psz_digest, digest_len) == 0) {
        fprintf(stderr, "Failed to finalize hash\n");
        goto end;
    }

    printf("Output digest:\n");
    BIO_dump_indent_fp(stdout, _psz_digest, digest_len, 2); /*!< 参数4是dump的宽度, 默认是16, 不用填写, 或者给0都行 */

    /* If digest length is 20 bytes, check it matches our known answer. */
    if (digest_len == 20) {
        /*
         * Always use a constant-time function such as CRYPTO_memcmp
         * when comparing cryptographic values. Do not use memcmp(3).
         */
        if (CRYPTO_memcmp(_psz_digest, known_answer, sizeof(known_answer)) != 0) {
            fprintf(stderr, "Output does not match expected result\n");
            goto end;
        }
    }

    ret = EXIT_SUCCESS;
end:
    OPENSSL_free(_psz_digest);
    EVP_MD_CTX_free(_evp_md_ctx);
    EVP_MD_free(_evp_md);
    OSSL_LIB_CTX_free(_ossl_lib_ctx);
    return ret;
}

END

相关推荐
Lazy Dave8 天前
gmssl私钥文件格式
网络安全·ssl·openssl
沉在嵌入式的鱼1 个月前
RK3588移植Openssl库
linux·rk3588·openssl
黑屋里的马1 个月前
ssl相关命令生成证书
服务器·网络·ssl·openssl·gmssl
fangeqin1 个月前
ubuntu源码安装python3.13遇到Could not build the ssl module!解决方法
linux·python·ubuntu·openssl
API开发2 个月前
苹果芯片macOS安装版Homebrew(亲测) ,一键安装node、python、vscode等,比绿色软件还干净、无污染
vscode·python·docker·nodejs·openssl·brew·homebrew
码农不惑2 个月前
Rust使用tokio(二)HTTPS相关
https·rust·web·openssl
liulilittle2 个月前
通过高级处理器硬件指令集AES-NI实现AES-256-CFB算法并通过OPENSSL加密验证算法正确性。
linux·服务器·c++·算法·安全·加密·openssl
liulilittle2 个月前
OpenSSL 的 AES-NI 支持机制
linux·运维·服务器·算法·加密·openssl·解密
liulilittle2 个月前
通过高级处理器硬件指令集AES-NI实现AES-256-CFB算法。
linux·服务器·c++·算法·安全·加密·openssl
花花少年2 个月前
Ubuntu系统下交叉编译openssl
openssl·交叉编译