为什么我在尝试使用Brian Gladman博士时会出现SEGFULT';s AES-GCM?

为什么我在尝试使用Brian Gladman博士时会出现SEGFULT';s AES-GCM?,c,encryption,segmentation-fault,aes,C,Encryption,Segmentation Fault,Aes,我正在尝试使用Brian Gladman博士著名的AES加密例程,在本例中是Galois计数器模式版本,我得到一个segfault,无法找到原因 我已经写了一个小的演示程序,展示了我正在尝试做的事情,事实上它看起来是可行的,但最后它还是失败了 我对C语言有点生疏,所以这个错误对聪明人来说是显而易见的 这是我的程序,我希望它尽可能简短易读: /* This program tries to be a demo for Dr Brian Gladman's AES-GCM encryption co

我正在尝试使用Brian Gladman博士著名的AES加密例程,在本例中是Galois计数器模式版本,我得到一个segfault,无法找到原因

我已经写了一个小的演示程序,展示了我正在尝试做的事情,事实上它看起来是可行的,但最后它还是失败了

我对C语言有点生疏,所以这个错误对聪明人来说是显而易见的

这是我的程序,我希望它尽可能简短易读:

/* This program tries to be a demo for Dr Brian Gladman's AES-GCM encryption code.
   The plan is to use AES-GCM to encrypt a short message, and provide an authentication key.
   And then to decrypt the ciphertext, verifying the authentication tag on the way.*/

#include<stdio.h>
#include<assert.h>

#include "aes-modes/gcm.h"

/*note that uint_8t is Dr Gladman's type, not to be confused with uint8_t from C99*/

void print_uint_8t_array(uint_8t *a, int len, char* name)
{
  int i;
  printf("%-10s:", name);

  for(i=0; i< len; i++){
    if(a[i]==0x00) printf("-");
    else if(a[i]>=0x20 && a[i]<=0x7e) printf("%c", a[i]); 
    else printf("~");
  }
  printf("\n");
}

#define p8(name) (print_uint_8t_array((name), (sizeof(name)), (#name)))

/*Dr Gladman's functions return 0,1 or -1, to be interpreted so:*/
void interpret_retval(AES_RETURN retval){
  switch(retval){
  case      0: 
    printf("RETURN_GOOD\n");
    break;
  case 1:
    printf("RETURN_WARN\n");
    break;
  case -1:
    printf("RETURN_ERROR\n");
    break;
  default: printf("Unknown return value");
    assert(0);
    break;
  }
}

int main(void){
  printf("GCM-AES encryption/decryption/authentication example\n");

  aes_init(); 
  /*I think that this is only needed if you've compiled the libraries to make up
    their tables at runtime. If the tables are compiled in, then it's
    unnecessary but probably doesn't do any harm.*/

  uint_8t key[32]="01234567890123456789012345678901"; 
  uint_8t iv[32]="01234567890123456789012345678901";

  uint_8t header[]="Here is a header, which is not to be encrypted, but which is nevertheless to be proved to have been placed in the message by someone who knows the key.";
  uint_8t message[]="Here is some text which is to be protected from the prying eyes of those who do not know the key, whilst at the same time it is to carry along with it an unencrypted header, and a with them both a tag proving beyond reasonable doubt that the two were packaged together and run through the aes-gcm algorithm by someone who knew the key."; 
  uint_8t tag[32]="01234567890123456789012345678901";

  void printtexts(void)
  {
    printf("-----------------------------------\n");
    p8(key);
    p8(iv);
    printf("-----------------------------------\n");
    p8(header);
    p8(message);
    p8(tag);
    printf("-----------------------------------\n");
  }

  printtexts();

  {
    gcm_ctx ecx[1];
    printf("encrypting....\n");
    gcm_init_and_key(key, sizeof(key), ecx);
    interpret_retval(gcm_encrypt_message(iv, sizeof(iv), header, sizeof(header), message, sizeof(message), tag, sizeof(tag), ecx));
    gcm_end(ecx);
    printf("done\n");
  }

  printtexts();

  {
    gcm_ctx dcx[1];

    printf("decrypting....\n");
    gcm_init_and_key(key, sizeof(key), dcx);
    interpret_retval(gcm_decrypt_message(iv, sizeof(iv), header, sizeof(header), message, sizeof(message), tag, sizeof(tag), dcx));
    gcm_end(dcx);
    printf("done\n");
  }

  printtexts();

  return 0;

}
/*此程序尝试作为Brian Gladman博士AES-GCM加密代码的演示。
计划是使用AES-GCM加密短消息,并提供身份验证密钥。
然后解密密文,在途中验证身份验证标签*/
#包括
#包括
#包括“aes模式/gcm.h”
/*请注意,uint_8t是Gladman博士的类型,不要与C99中的uint8_t混淆*/
无效打印uint\u 8t\u数组(uint\u 8t*a,int len,char*name)
{
int i;
printf(“%-10s:”,名称);
对于(i=0;i如果(a[i]>=0x20&&a[i]自动应答,以防其他人对使用这些例程感兴趣

显然,AES-GSM的最大标签大小是16字节。将标签长度更改为16或更少(我这里的标签长度为32),一切正常

这一限制似乎是硬编码到gcm_decrypt_消息中的块大小。将其更改为32似乎也可行,但只有上帝知道这对算法的加密属性有什么影响

在调试说明中,gcc有一个选项-fstack-protector-all,它可以在破坏返回堆栈时捕获所有库,这就是这里发生的事情


据我所知,segfault是在main试图返回库写入堆栈的完全虚构的地址时引起的。

如果我正确读取输出,则segfault似乎发生在最后一次调用
printtexts()之后
。可能是什么东西损坏了堆栈?请注意,解密过程中出现了一个错误——找出导致错误的原因,也许您的segfault也会得到解决。谢谢,这是一个很好的建议,尽管事实上我最终发现堆栈被破坏的地方,这导致了“密钥对于l中的局部变量来说太大”问题的根源。谷歌搜索导致AES-GSM标记被限制为16个字节。该标记最多可以是分组密码的一个完整块大小。由于AES有16个字节的块,因此不可能超过16个字节。(我没有查看实现以了解更大的尺寸会产生什么影响,但您肯定不会有标准的AES-GCM。)
jla@jaspden-desktop$ ./test3
GCM-AES encryption/decryption/authentication example
-----------------------------------
key       :01234567890123456789012345678901
iv        :01234567890123456789012345678901
-----------------------------------
header    :Here is a header, which is not to be encrypted, but which is nevertheless to be proved to have been placed in the message by someone who knows the key.-
message   :Here is some text which is to be protected from the prying eyes of those who do not know the key, whilst at the same time it is to carry along with it an unencrypted header, and a with them both a tag proving beyond reasonable doubt that the two were packaged together and run through the aes-gcm algorithm by someone who knew the key.-
tag       :01234567890123456789012345678901
-----------------------------------
encrypting....
RETURN_GOOD
done
-----------------------------------
key       :01234567890123456789012345678901
iv        :01234567890123456789012345678901
-----------------------------------
header    :Here is a header, which is not to be encrypted, but which is nevertheless to be proved to have been placed in the message by someone who knows the key.-
message   :~(}Hr~|o~~:~D~~~~3~~T~C~C(l~~~'~~~UC~D~~~~&O~ ~L~-~~~E&~~~~!~~~~~K~~~~M<|l%<ho~"~[A~0~~O~3T~%8K~~~L~~~~~~~~~7~~~~~~~~e~~~~;~392~8<~~ ~~v,E~~~~~~~~~~~W~yd~~C$H~~~*r~~~_~~~~O~u~h\9s~~`%~~~~~&~~~~~~.~~Q~~~Y~Ix~A~~~a5~~~~|~~9J~~~~~~~~ ~~ZOiX~~~~~~f~~`e~~~Ju~Z~~~X~g~OX~C~~~~~~~~~(~~gyT~~x~L~4>~Z~~ge~~~08~;~@~s~3~~WA~~~~Z-~~~~/~~~~~~Tj~bL~~
tag       :|~~,~2~~Ec~~~A~~~~~_j{~~~~`~~~u~
-----------------------------------
decrypting....
RETURN_ERROR
done
-----------------------------------
key       :01234567890123456789012345678901
iv        :01234567890123456789012345678901
-----------------------------------
header    :Here is a header, which is not to be encrypted, but which is nevertheless to be proved to have been placed in the message by someone who knows the key.-
message   :Here is some text which is to be protected from the prying eyes of those who do not know the key, whilst at the same time it is to carry along with it an unencrypted header, and a with them both a tag proving beyond reasonable doubt that the two were packaged together and run through the aes-gcm algorithm by someone who knew the key.-
tag       :|~~,~2~~Ec~~~A~~~~~_j{~~~~`~~~u~
-----------------------------------
Segmentation fault (core dumped)