密码库LibTomCrypt学习记录——(2.25)分组密码算法的工作模式——EAX加密认证模式

本文深入探讨了EAX加密认证模式,一种结合了加密和认证功能的安全算法。EAX由Mihir Bellare等人提出,旨在替代CCM标准,提供更优的性能和简化的设计。文章详细介绍了EAX的工作原理、加密流程以及LibTomCrypt库中实现的相关函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. EAX

EAX是一种加密认证模式,它可以对消息明文进行加密,同时对消息明文和关联信息(Associated Data)进行认证,当然此关联信息也可以为空。EAX由Mihir Bellare等人在2003年提交给NIST,其目的是希望取代现在的CCM标准。因为相较之下,EAX有更好的表现,而CCM显得较为复杂。但到目前为止,EAX还没有取代CCM。

EAX参考文献

  1. Mihir Bellare, Phillip Rogaway, and David Wagner, The EAX Mode of Operation, FSE 2004, LNCS 3017, pp. 389–407, 2004.
  2. Mihir Bellare, Phillip Rogaway, and David Wagner, The EAX Mode of Operation(A Two-Pass Authenticated-Encryption Scheme Optimized for Simplicity and Efficiency), A preliminary full version appears in Fast Software Encryption ’04, Lecture Notes in Computer Science.
  1. EAX算法

EAX加密流程

输入:

  1. K:密钥
  2. M:明文
  3. N:随机数
  4. H:不需加密仅需认证的关联信息

输出:

  1. C:密文
  2. CT:认证MAC值(t bit)

EAX的加密流程图如下:

图 EAX加密流程图

  1. LibTomCrypt与EAX

记录EAX信息的结构体是eax_state,其结构如下

typedef struct {

   unsigned char N[MAXBLOCKSIZE];

   symmetric_CTR ctr;

   omac_state headeromac, ctomac;

} eax_state;//ctomac记录了OMAC_K( [2]_128 || c)的信息。

参数说明

  1. N = LTC_OMAC_0K(nonce) = OMAC_K( [0]_128 || nonce),在eax_init()中被计算出来,在eax_done()中使用此N值。
  2. ctr记录了CTR加密模式的工作状态。
  3. headeromac记录了OMAC_K( [1]_128 || header)的信息。为方便继续添加header,故而采用 omac_state,这样以后可以调用eax_addheader()添加header。
  4. ctomac记录密文的omac信息状态。

eax涉及函数如下。

int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen);

int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);

int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length);

int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length);

int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen);

int eax_encrypt_authenticate_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen);

int eax_decrypt_verify_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce,  unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, unsigned char *tag, unsigned long taglen, int *stat);

int eax_test(void);

──────────────────────────────────────

int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen)

// [功能]   初始化EAX

  1. cipher           // [输入] 密码算法
  2. key                   // [输入] 密钥
  3. keylen          // [输入] 密钥长度
  4. nonce           // [输入] 随机数
  5. noncelen           // [输入] 随机数长度
  6. header              // [输入] 关联信息
  7. headerlen     // [输入] 关联信息长度
  8. eax                   // [输入/输出] EAX状态

//备注: 处理过程如下

//1. 计算 N = LTC_OMAC_0K(nonce)  = OMAC_K( [0]_128 || nonce)

//2. 计算 H = LTC_OMAC_0K(header) = OMAC_K( [1]_128 || header)

//       为方便继续添加header,此处计算出来的H还没有封口,所以采用 omac_state

//3. 初始化 CTR 模式

//4. 计算 C` = LTC_OMAC_2K(C) = OMAC_K( [2]_128 || C)的第一个分组[2]_128

//       这里的OMAC^t_K(M) = OMAC_K( [t]n || M)

//       [t]n是t的n bit表示形式,这里就是将t表示为一个分组长度──────────────────────────────────────

──────────────────────────────────────

int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);

// [功能]   加密与认证

  1. pt                // [输入] 明文
  2. ct                // [输出] 密文
  3. length          // [输入] 明文长度
  4. eax                   // [输入/输出] EAX状态

//备注:处理过程为

//1. 先用CRT加密得到密文

//2. 再用OMAC处理加密得到的密文

──────────────────────────────────────

──────────────────────────────────────

int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length)

// [功能]   解密与验证

  1. out               // [输出] MAC
  2. outlen          // [输入/输出] MAC长度
  3. eax                   // [输入/输出] eax的状态

//备注:-

──────────────────────────────────────

──────────────────────────────────────

int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length)

// [功能] 继续添加 head信息

  1. header              // [输入] 关联信息
  2. length          // [输入/输出] 关联信息长度
  3. eax                   // [输入/输出] eax的状态

//备注:主要应对head信息也是流式数据需不断添加的情况

──────────────────────────────────────

──────────────────────────────────────

int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen)

// [功能]   结束EAX,得到最终mac值 tag

  1. tag               // [输出] MAC
  2. tag len              // [输出] MAC长度
  3. eax                   // [输入/输出] eax的状态

//备注: 主要做以下三件事情

//Step1. 结束ct的omac工作,得到ctmac

//Step2. 结束header的omac工作,得到headermac

//step3. 三项异或得到MAC值

──────────────────────────────────────

──────────────────────────────────────

int eax_encrypt_authenticate_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen)

// [功能]   处理消息并输出MAC(即加密认证一段数据)

  1. cipher           // [输入] 密码算法
  2. key                   // [输入] 密钥
  3. keylen          // [输入] 密钥长度
  4. nonce           // [输入] 随机数
  5. noncelen           // [输入] 随机数长度
  6. header              // [输入] 关联信息
  7. headerlen     // [输入] 关联信息长度
  8. pt                // [输入] 明文
  9. ptlen            // [输入] 明文长度
  10. ct                // [输出] 密文
  11. tag               // [输出] MAC
  12. tag len              // [输出] MAC长度

//备注: 实际是对整个EAX过程的一个简单封装。

// 这要求所有消息和附加的认证信息都不能太长,且不能再次添加

// 工作流程为:

// 1. eax_init( )

// 2. eax_encrypt( )

// 3. eax_done( )

──────────────────────────────────────

──────────────────────────────────────

int eax_decrypt_verify_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce,  unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, unsigned char *tag, unsigned long taglen, int *stat)

// [功能]   验证并解密一段数据

  1. cipher           // [输入] 密码算法
  2. key                   // [输入] 密钥
  3. keylen          // [输入] 密钥长度
  4. nonce           // [输入] 随机数
  5. noncelen           // [输入] 随机数长度
  6. header              // [输入] 关联信息
  7. headerlen     // [输入] 关联信息长度
  8. ct                // [输入] 密文
  9. ctlen            // [输入] 密文长度
  10. pt                // [输出] 明文
  11. tag               // [输出] MAC
  12. tag len              // [输出] MAC长度

//备注:实际是对整个EAX解密验证过程的一个简单封装。

// 这要求所有消息和附加的认证信息都不能太长,且不能再次添加

// 工作流程为:

// 1. eax_init( )

// 2. eax_decrypt( )

// 3. eax_done( )

──────────────────────────────────────

──────────────────────────────────────

int eax_test(void)

// [功能]   测试函数

──────────────────────────────────────

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值