开发者
资源
我要评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

SM3算法调用示例

将以下代码保存为sm3_demo.c后,编译运行。

gcc -o sm3_demo sm3_demo.c -lssl -lcrypto -ldl
./sm3_demo
/**
 * sm3_demo.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#define ENGINE_SO_PATH   "/usr/lib64/libsdf_engine.so"
#define SDF_LIB_PATH     "/usr/lib64/libsdf.so"
static ENGINE *g_engine = NULL;
/* 预期的 SM3("abc") 哈希值 */
static const unsigned char expected_sm3_hash[] = {
    0x66, 0xc7, 0xf0, 0xf4, 0x62, 0xee, 0xed, 0xd9,
    0xd1, 0xf2, 0xd4, 0x6b, 0xdc, 0x10, 0xe4, 0xe2,
    0x41, 0x67, 0xc4, 0x87, 0x5c, 0xf2, 0xf7, 0xa2,
    0x29, 0x7d, 0xa0, 0x2b, 0x8f, 0x4b, 0xa8, 0xe0
};
static ENGINE* load_engine(const char *so_path, const char *sdf_lib_path) {
    ENGINE_load_dynamic();
    ENGINE *e = ENGINE_by_id("dynamic");
    if (!e) {
        fprintf(stderr, "Failed to get dynamic ENGINE\n");
        return NULL;
    }
    if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", so_path, 0)) goto err;
    if (!ENGINE_ctrl_cmd_string(e, "ID", "sdf", 0)) goto err;
    if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) goto err;
    if (!ENGINE_ctrl_cmd_string(e, "SDF_LIB_PATH", sdf_lib_path, 0)) goto err;
    if (!ENGINE_init(e)) goto err;
    return e;
err:
    ENGINE_free(e);
    return NULL;
}
static void test_sm3_oneshot(void) {
    unsigned char md[EVP_MAX_MD_SIZE];
    unsigned int mdlen = 0;
    const char *msg = "abc";
    if (EVP_Digest((const unsigned char*)msg, strlen(msg), md, &mdlen, EVP_sm3(), g_engine) != 1) {
        fprintf(stderr, "EVP_Digest failed\n");
        exit(EXIT_FAILURE);
    }
    if (mdlen != 32 || memcmp(md, expected_sm3_hash, 32) != 0) {
        fprintf(stderr, "SM3 oneshot hash mismatch\n");
        exit(EXIT_FAILURE);
    }
    printf("SM3 oneshot: OK\n");
}
static void test_sm3_stream(void) {
    unsigned char md[EVP_MAX_MD_SIZE];
    unsigned int mdlen = 0;
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
    if (!ctx) {
        fprintf(stderr, "EVP_MD_CTX_new failed\n");
        exit(EXIT_FAILURE);
    }
    if (EVP_DigestInit_ex(ctx, EVP_sm3(), g_engine) != 1) {
        fprintf(stderr, "DigestInit failed\n");
        EVP_MD_CTX_free(ctx);
        exit(EXIT_FAILURE);
    }
    if (EVP_DigestUpdate(ctx, "abc", 3) != 1) {
        fprintf(stderr, "DigestUpdate failed\n");
        EVP_MD_CTX_free(ctx);
        exit(EXIT_FAILURE);
    }
    if (EVP_DigestFinal_ex(ctx, md, &mdlen) != 1) {
        fprintf(stderr, "DigestFinal failed\n");
        EVP_MD_CTX_free(ctx);
        exit(EXIT_FAILURE);
    }
    EVP_MD_CTX_free(ctx);
    if (mdlen != 32 || memcmp(md, expected_sm3_hash, 32) != 0) {
        fprintf(stderr, "SM3 stream hash mismatch\n");
        exit(EXIT_FAILURE);
    }
    printf("SM3 stream: OK\n");
}
int main(void) {
    printf("Loading ENGINE...\n");
    g_engine = load_engine(ENGINE_SO_PATH, SDF_LIB_PATH);
    if (!g_engine) {
        fprintf(stderr, "Engine load failed\n");
        return EXIT_FAILURE;
    }
    printf("Engine loaded.\n");
    test_sm3_oneshot();
    test_sm3_stream();
    ENGINE_free(g_engine);
    ENGINE_cleanup();
    printf("All SM3 tests passed.\n");
    return EXIT_SUCCESS;
}