本文针对 OpenSSL 1.1.1 版,以下内容大部分来自对 \OpenSSL\html\man3\ 目录下 EVP_MD_ 开头的 html 文件的摘录和翻译。

-----------------------------------------------
EVP_MD_CTX 和 EVP_MD 的定义

在 OpenSSL 1.1.1 源码 \crypto\evp\evp_locl.h 中定义了结构体 evp_md_ctx_st, 如下:

struct evp_md_ctx_st {
    const EVP_MD *digest;
    ENGINE *engine;
    unsigned long flags;
    void *md_data;
    EVP_PKEY_CTX *pctx;
    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
} /* EVP_MD_CTX */ ;

在 OpenSSL 1.1.1 源码 \crypto\include\internal\evp_int.h 中定义了结构体 evp_md_st,如下:

struct evp_md_st {
    int type;
    int pkey_type;
    int md_size;
    unsigned long flags;
    int (*init) (EVP_MD_CTX *ctx);
    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
    int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
    int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
    int (*cleanup) (EVP_MD_CTX *ctx);
    int block_size;
    int ctx_size;
    int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
} /* EVP_MD */ ;

在 \include\openssl\ossl_typ.h 中定义了以下宏:

typedef struct evp_md_st EVP_MD;

typedef struct evp_md_ctx_st EVP_MD_CTX;

-----------------------------------------------
和计算摘要有关的部分函数

EVP_MD_CTX *EVP_MD_CTX_new(void);
动态分配一个摘要上下文(digest context)所需的内存空间,并返回指向这个摘要上下文的指针。

void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
清理参数 ctx 指向的摘要上下文内存空间,然后释放这一段内存。

int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
重置参数 ctx 指向的摘要上下文,用户可以使用本函数来重用一个已经创建的摘要上下文,而不是再创建一个新的摘要上下文。

int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
使用摘要类型参数 type、引擎参数 impl 初始化摘要上下文参数 ctx 。参数 type 的值可以是以下函数的返回值:EVP_sha256( ), EVP_sha384( ),EVP_sha512( ),EVP_sm3( )等。当参数 impl 的值为 NULL 时,使用默认的引擎计算摘要值。

int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
与 EVP_DigestInit_ex( ) 类似,但总是使用默认的引擎计算摘要值。

int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
针对参数 d 指向的输入缓冲区中长度为 cnt 字节的数据计算摘要值。当原始数据长度较长、难以被一次性的读入内存缓冲区时,可以将数据分批读入缓冲区,反复调用该函数来计算摘要值,在这种情况下,每次调用该函数时参数 ctx 的值必须相同。

int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);
从参数 ctx 中获取摘要值,放入参数 md 指向的缓冲区。如果参数 s 的值不是空指针,将摘要的长度赋值给指针 s 指向的整型变量。对于标准的摘要算法,其杂凑值长度是固定的,用户能够提前知道摘要值长度,不需要通过调用 EVP_DigestFinal_ex( ) 获取杂凑值长度,此时可以将变量 s 的值直接赋为 NULL,但是一定要保证用来存放摘要值的缓冲区长度足够容纳。调用 EVP_DigestFinal_ex( ) 函数将终结摘要计算过程,在此之后不能再调用 EVP_DigestUpdate( ) 函数。
EVP_DigestFinal_ex( ) 函数的实现在 \crypto\evp\digest.c 中,内部包含以下语句:
if (size != NULL)
   *size = ctx->digest->md_size;

int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);
与 EVP_DigestFinal_ex( ) 类似,并且该函数会重置 ctx 指向的摘要上下文。
该函数的实现在 \crypto\evp\digest.c 中,如下:

int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
{
    int ret;
    ret = EVP_DigestFinal_ex(ctx, md, size);
    EVP_MD_CTX_reset(ctx);
    return ret;
}

int EVP_MD_type(const EVP_MD *md);
当输入参数是一个 EVP_MD 结构体时,返回该摘要算法对象识别符对应的 NID。例如:EVP_MD_type(EVP_sha1()) 的返回值是 NID_sha1 。
如果根据输入的 EVP_MD 找不到对应的摘要算法,将返回 NID_undef 。

注意:
NID_sha1, NID_undef 都是在 \include\openssl\obj_mac.h 中定义的宏,常见的一些 NID 定义如下:

#define NID_undef                      0
#define NID_sha1                       64
#define NID_sha256                     672
#define NID_sha256WithRSAEncryption    668
#define NID_sm3                        1143

const EVP_MD *EVP_get_digestbynid(int type);
当输入值是一个摘要 NID 时,例如 NID_sha1,返回一个 EVP_MD 结构体。如果根据摘要 NID 找不到对应的摘要算法,将返回 NULL。

注意:
从 OpenSSL 1.1.0 版开始,以前版本中的 EVP_MD_CTX_create( ) 被重命名为 EVP_MD_CTX_new,EVP_MD_CTX_init( ) 被重命名为 EVP_MD_CTX_reset( ),EVP_MD_CTX_destroy( ) 被重命名为 EVP_MD_CTX_free( )。
在 OpenSSL 1.1.1 版的 \include\openssl\evp.h 文件中,可以看到以下宏定义:

# define EVP_MD_CTX_create()     EVP_MD_CTX_new()
# define EVP_MD_CTX_init(ctx)    EVP_MD_CTX_reset((ctx))
# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx))

OpenSSL 中的 EVP_MD 学习笔记(针对1.1.1版本)相关推荐

  1. Python中索引的学习笔记

    1 前言 今天在学习FaceBoxes- 看到一个比较奇怪的代码,"order = scores.argsort()[::-1][:args.top_k]",不太懂这个" ...

  2. 机器人学中的状态估计——学习笔记

    机器人学中的状态估计--学习笔记 离散时间的批量估计问题 1.最大后验概率法(Maximum A Posteriori, MAP) 2.贝叶斯推断(Bayesian inference) 离散时间的迭 ...

  3. 机器人学中的状态估计学习笔记(二)第三章线性高斯系统的状态估计

    机器人学中的状态估计学习笔记(二)第三章线性高斯系统的状态估计 3.1 离散时间的批量估计问题 3.1.1 问题定义 3.1.2 最大后验估计 3.1.3 贝叶斯推断 3.1.4 存在性.唯一性与能观 ...

  4. java学习笔记:全部,txt版本

    java学习笔记:全部,txt版本 笔者注: 1.不知道怎么上传附件,所以就把txt文本内容全部贴在这里吧. 2.已经把txt版本的笔记上传到CSDN了,我没有设置索要积分才能下载,但是不知道为什么C ...

  5. 英伟达DeepStream学习笔记27——deepstream下载历史版本

    英伟达DeepStream学习笔记27--deepstream下载历史版本 https://docs.nvidia.com/metropolis/deepstream-archive.html htt ...

  6. 我的Android进阶之旅------gt;Android中编解码学习笔记

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  7. zynq中interrupts的学习笔记(一)

    本学习笔记参考UG585-Zynq-7000-TRM.pdf ch.7:Interrupts.文中有说的不够严谨或者是有错误的地方,欢迎指正! zynq中的interrupts有很多种,大体上分为三类 ...

  8. Java中expecial,RxJava 学习笔记 (一)

    作者: 一字马胡 转载标志 [2017-12-13] 更新日志 日期 更新内容 备注 2017-12-13 RxJava学习笔记系列 系列笔记 (一) 2017-12-15 增加系列笔记(二) 201 ...

  9. JavaSE中Map框架学习笔记

    前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...

最新文章

  1. SQL server数据库日志满了怎么处理?
  2. 【软件】chrome设置默认字体
  3. PHP的JSON封装
  4. python骂人的程序_Python实现敏感词过滤的4种方法
  5. 8个使用JavaScript展示图片解决方案
  6. 程序员过关斩将--应对高并发系统有没有通用的解决方案呢?
  7. NCRE四级网络工程师考题详解----目录分解法
  8. pandownload限速原因及解决方案
  9. 华三服务器管理口地址_不同型号服务器的默认管理IP及账号密码汇总
  10. How to Create Your Own HDR Environment Maps
  11. MySQL索引原理以及查询优化
  12. 计算机辅助审计笔记,审计笔记2.0 盘点
  13. 联想惠普谁才是pc的最后王者
  14. [机器学习]决策树选西瓜
  15. redis学习之redis的发布和订阅
  16. 淘宝HTML5版私钥泄漏
  17. html5script计时器,javascript实现秒表计时器的制作方法
  18. 某宝 小黑屋 x-sg?xt x-si?n x-m?ni-w?a 分析学习
  19. 华为云GaussDB(for Redis)GaussDB(for Redis)全面对比Codis
  20. 玩转Google开源C++单元测试框架

热门文章

  1. CSS 设置超链接格式
  2. 洛谷-2151 [SDOI2009]HH去散步
  3. 跳槽多次后,月薪等于老同事的年薪
  4. ew传输_ew。 好一个星期。 重新发现基础知识。
  5. 趣味算法-求波峰波谷最大值
  6. 游戏服务器如何选择合适的服务器配置
  7. cesium态势标绘 ( 绘制矩形)
  8. 新手教程--手把手教你从零开始制作一款电商必备的商城小程序
  9. vscode 中出现 Bad owner or permissions on .ssh/config
  10. 老子云已来黑科技,我们都是设计师 !