我有下面的C程序试图使用MbedTLS AES GCM函数进行加密和解密。加密运行良好但在mbedtls_cipher_check_tag()中解密为rc = -25344(-0x6300)。对于该返回码,mbedtls_strerror返回“上次错误为:-0x6300 - CIPHER - 身份验证失败(针对AEAD模式)”。
虽然文档说它放在mbedtls_cipher_finish()之后,但我试图在没有成功的情况下更改函数的位置(如代码中所示)。
我做错了什么,有什么想法? 任何帮助都非常有价值。
提前致谢
这里是代码:
//#
//# AES 128 GCM - MbedTLS
//#
#include <mbedtls/cipher.h>
#include <mbedtls/gcm.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "etss.h"
#define PLAIN_SIZE 1024
#define CRYPT_SIZE 1032
key128 k;
iv16 iv;
aad16 aad;
tag16 tag;
int Decrypta (FILE * fInput, FILE * fOutput)
{
int conta = 0, rc = 0;
int nBytesWorked = 0, nGCMfinal = 0;
int nBytesRead = 0, nBytesWritten = 0;
int cIn = 0, cOut = 0, cWorked = 0;
unsigned char sPureBuff[PLAIN_SIZE] __attribute__((aligned(16))), sCiphBuff[CRYPT_SIZE] __attribute__((aligned(16)));
unsigned char *pPureBuff __attribute__((aligned(16)));
unsigned char *pCiphBuff __attribute__((aligned(16)));
unsigned char *pTag = tag.data;
pPureBuff = sPureBuff;
pCiphBuff = sCiphBuff;
mbedtls_cipher_context_t ctx;
mbedtls_cipher_init (&ctx);
rc = mbedtls_cipher_setup (&ctx, mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, k.size*8, MBEDTLS_MODE_GCM));
if ( rc != 0 )
{
printf ("Setup - Context preparation error (rc = %d). \n", rc);
return rc;
}
rc = mbedtls_cipher_setkey (&ctx, k.data, k.size*8, MBEDTLS_DECRYPT);
if ( rc != 0 )
{
printf ("Set Key - Context preparation error (rc = %d). \n", rc);
return rc;
}
rc = mbedtls_cipher_set_iv (&ctx, iv.data, iv.size);
if ( rc != 0 )
{
printf ("Set IV - Context preparation error (rc = %d). \n", rc);
return rc;
}
// rc = mbedtls_cipher_check_tag (&ctx, pTag, (size_t) tag.size);
//
// if ( rc != 0 )
// {
// printf ("Decryption - Error in check_tag() (rc=%d).\n",rc);
// return rc;
// }
rc = mbedtls_cipher_reset (&ctx);
if ( rc != 0 )
{
printf ("Reset - Context preparation error (rc = %d). \n", rc);
return rc;
}
rc = mbedtls_cipher_update_ad (&ctx, aad.data, aad.size);
if ( rc != 0 )
{
printf ("Set AAD - Context preparation error (rc = %d). \n", rc);
return rc;
}
memset(pCiphBuff, 0, CRYPT_SIZE);
memset(pPureBuff, 0, PLAIN_SIZE);
if ( (rc = ReadFile (fInput, &pCiphBuff, 1, CRYPT_SIZE, &nBytesRead)) )
{
printf ("Decryption - Input file reading error (rc = %d). \n", rc);
return rc;
}
while ( nBytesRead > 0 )
{
cIn += nBytesRead;
nBytesWorked = 0;
rc = mbedtls_cipher_update (&ctx, sCiphBuff, nBytesRead, sPureBuff, (size_t *) &nBytesWorked);
if ( rc != 0 )
{
printf ("Decryption - Error in DecryptUpdate() (rc = %d).\n", rc);
return rc;
}
cWorked += nBytesWorked;
// Count decryptions
conta++;
if ( nBytesWorked != 0 )
{
if ( (rc = WriteFile (fOutput, sPureBuff, 1, cWorked, &nBytesWritten)) )
{
printf ("Decryption - Output file writing error (rc = %d).\n", rc);
return rc;
}
pPureBuff = sPureBuff;
memset(pPureBuff, 0, PLAIN_SIZE);
cOut += nBytesWritten;
cWorked = 0;
}
if ( (rc = ReadFile (fInput, &pCiphBuff, 1, CRYPT_SIZE, &nBytesRead)) )
{
printf ("Decryption - Input file reading error (rc = %d). \n", rc);
return rc;
}
}
// rc = mbedtls_cipher_check_tag (&ctx, pTag, (size_t) tag.size);
//
// if ( rc != 0 )
// {
// printf ("Decryption - Error in check_tag() (rc=%d).\n",rc);
// return rc;
// }
pPureBuff += cWorked;
rc = mbedtls_cipher_finish (&ctx, pPureBuff, (size_t *) &nGCMfinal);
if ( rc != 0 )
{
printf ("Decryption - Error in DecryptFinal() (rc=%d).\n",rc);
return rc;
}
// Count decryptions
conta++;
rc = mbedtls_cipher_check_tag (&ctx, pTag, (size_t) tag.size);
if ( rc != 0 )
{
printf ("Decryption - Error in check_tag() (rc=%d).\n",rc);
return rc;
}
cWorked += nBytesWorked;
if ( (rc = WriteFile (fOutput, sPureBuff, 1, cWorked, &nBytesWritten)) )
{
printf ("Decryption - Output file writing error (rc = %d).\n", rc);
return rc;
}
cOut += nBytesWritten;
printf("\tD %d cIn = %d cOut = %d\n\n", conta, cIn, cOut);
mbedtls_cipher_free (&ctx);
return 0;
}
int Encrypta (FILE * fInput, FILE * fOutput)
{
int conta = 0, rc = 0;
int nBytesWorked = 0, nGCMfinal = 0;
int nBytesRead = 0, nBytesWritten = 0;
int cIn = 0, cOut = 0, cWorked = 0;
unsigned char sPureBuff[PLAIN_SIZE] __attribute__((aligned(16))), sCiphBuff[CRYPT_SIZE] __attribute__((aligned(16)));
unsigned char *pPureBuff __attribute__((aligned(16)));
unsigned char *pCiphBuff __attribute__((aligned(16)));
unsigned char *pTag = tag.data;
pPureBuff = sPureBuff;
pCiphBuff = sCiphBuff;
mbedtls_cipher_context_t ctx;
mbedtls_cipher_init (&ctx);
rc = mbedtls_cipher_setup (&ctx, mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, k.size*8, MBEDTLS_MODE_GCM));
if ( rc != 0 )
{
printf ("Setup - Context preparation error (rc = %d). \n", rc);
return rc;
}
rc = mbedtls_cipher_setkey (&ctx, k.data, k.size*8, MBEDTLS_ENCRYPT);
if ( rc != 0 )
{
printf ("Set Key - Context preparation error (rc = %d). \n", rc);
return rc;
}
rc = mbedtls_cipher_set_iv (&ctx, iv.data, iv.size);
if ( rc != 0 )
{
printf ("Set IV - Context preparation error (rc = %d). \n", rc);
return rc;
}
rc = mbedtls_cipher_reset (&ctx);
if ( rc != 0 )
{
printf ("Reset - Context preparation error (rc = %d). \n", rc);
return rc;
}
rc = mbedtls_cipher_update_ad (&ctx, aad.data, aad.size);
if ( rc != 0 )
{
printf ("Set AAD - Context preparation error (rc = %d). \n", rc);
return rc;
}
memset(pPureBuff, 0, PLAIN_SIZE);
memset(pCiphBuff, 0, CRYPT_SIZE);
if ( (rc = ReadFile (fInput, &pPureBuff, 1, PLAIN_SIZE, &nBytesRead)) )
{
printf ("Encryption - Input file reading error (rc = %d). \n", rc);
return rc;
}
while ( nBytesRead > 0 )
{
cIn += nBytesRead;
pCiphBuff += cWorked;
rc = mbedtls_cipher_update (&ctx, sPureBuff, nBytesRead, sCiphBuff, (size_t *) &nBytesWorked);
if ( rc != 0 )
{
printf ("Encryption - Error in EncryptUpdate() (rc = %d).\n", rc);
return rc;
}
cWorked += nBytesWorked;
// Count encryptions
conta++;
if ( nBytesWorked != 0 )
{
if ( (rc = WriteFile (fOutput, sCiphBuff, 1, cWorked, &nBytesWritten)) )
{
printf ("Encryption - Output file writing error (rc = %d).\n", rc);
return rc;
}
pCiphBuff = sCiphBuff;
memset(pCiphBuff, 0, CRYPT_SIZE);
cOut += nBytesWritten;
cWorked = 0;
}
if ( (rc = ReadFile (fInput, &pPureBuff, 1, PLAIN_SIZE, &nBytesRead)) )
{
printf ("Encryption - Input file reading error (rc = %d). \n", rc);
return rc;
}
}
pCiphBuff += cWorked;
rc = mbedtls_cipher_finish (&ctx, pCiphBuff, (size_t *) &nGCMfinal);
if ( rc != 0 )
{
printf ("Encryption - Error in EncryptFinal() (rc=%d).\n",rc);
return rc;
}
// Count encryptions
conta++;
rc = mbedtls_cipher_write_tag (&ctx, pTag, (size_t) tag.size);
if ( rc != 0 )
{
printf ("Encryption - Error in write_tag() (rc=%d).\n",rc);
return rc;
}
cWorked += nBytesWorked;
if ( (rc = WriteFile (fOutput, sCiphBuff, 1, cWorked, &nBytesWritten)) )
{
printf ("Encryption - Output file writing error (rc = %d).\n", rc);
return rc;
}
cOut += nBytesWritten;
printf("\tE %d cIn = %d cOut = %d\n\n", conta, cIn, cOut);
mbedtls_cipher_free (&ctx);
return 0;
}
int main (int argc, char *argv[])
{
FILE *fPlain = NULL, *fEncrypt = NULL, *fDecrypt = NULL;
k.size = 16;
unsigned char inKey[16] = {0x9A, 0x59, 0x4E, 0xFA, 0x2C, 0x40, 0xBC, 0xC1, 0x2A, 0x05, 0x64, 0x43, 0xAC, 0x0C, 0xC1, 0xC2};
iv.size = 16;
unsigned char inIV[16] = {0x57, 0x1D, 0x32, 0xCE, 0x4F, 0x43, 0x17, 0x38, 0xE5, 0x52, 0x69, 0xE2, 0x18, 0xD1, 0x32, 0x09};
aad.size = 16; tag.size = 16;
unsigned char inAAD[16] = {0x9A, 0x1D, 0x4E, 0xCE, 0x2C, 0x43, 0xBC, 0x38, 0x2A, 0x52, 0x64, 0xE2, 0xAC, 0xD1, 0xC1, 0x09};
strncpy((char *) k.data, (const char *) inKey, k.size);
strncpy((char *) iv.data, (const char *) inIV, iv.size);
strncpy((char *) aad.data, (const char *) inAAD, aad.size);
int rc = 0;
if ( (rc = OpenFile (&fPlain, argv[1], "r")) )
{
printf ("GCM128-M - Open input plain text file %s error (rc = %d).\n", argv[1], rc);
return rc;
}
fEncrypt = fopen (argv[2], "wb+");
rc = errno;
if ( fEncrypt == NULL )
{
printf ("GCM128-M - Open output encrypt text file %s error (rc = %d).\n", argv[2], rc);
return rc;
}
printf("\n>> Encrypting AES GCM 128 ...\n\n");
Encrypta (fPlain, fEncrypt);
CloseFile(fPlain);
CloseFile(fEncrypt);
fEncrypt = fopen (argv[2], "rb+");
rc = errno;
if ( fEncrypt == NULL )
{
printf ("GCM128-M - Open input encrypt text file %s error (rc = %d).\n", argv[2], rc);
return rc;
}
if ( (rc = OpenFile (&fDecrypt, argv[3], "w")) )
{
printf ("GCM128-M - Open output decrypt text file %s error (rc = %d).\n", argv[3], rc);
return rc;
}
printf("\n>> Decrypting AES GCM 128 ...\n\n");
Decrypta (fEncrypt, fDecrypt);
CloseFile(fEncrypt);
CloseFile(fDecrypt);
return 0;
}
etss.h(由Gilles提问)是:
#ifndef ETSS_H_
#define ETSS_H_
typedef struct st_key128 {
unsigned char data[16];
int size;
} key128;
typedef struct st_key192 {
unsigned char data[24];
int size;
} key192;
typedef struct st_key256 {
unsigned char data[32];
int size;
} key256;
typedef struct st_iv8 {
unsigned char data[8];
int size;
} iv8;
typedef struct st_iv16 {
unsigned char data[16];
int size;
} iv16;
typedef struct st_iv32 {
unsigned char data[32];
int size;
} iv32;
typedef struct st_aad8 {
unsigned char data[8];
int size;
} aad8;
typedef struct st_aad16 {
unsigned char data[16];
int size;
} aad16;
typedef struct st_aad32 {
unsigned char data[32];
int size;
} aad32;
typedef struct st_tag8 {
unsigned char data[8];
int size;
} tag8;
typedef struct st_tag16 {
unsigned char data[16];
int size;
} tag16;
int InitKey128(key128 * key);
int InitKey192(key192 * key);
int InitKey256(key256 * key);
int InitIV8(iv8 * iv);
int InitIV16(iv16 * iv);
int InitIV32(iv32 * iv);
int InitAAD8(aad8 * iv);
int InitAAD16(aad16 * iv);
int InitAAD32(aad32 * iv);
int InitTAG8(tag8 * iv);
int InitTAG16(tag16 * iv);
int SetKey128(key128 * key, char * keyValue);
int SetKey192(key192 * key, char * keyValue);
int SetKey256(key256 * key, char * keyValue);
int SetIV8(iv8 * iv, char * ivValue);
int SetIV16(iv16 * iv, char * ivValue);
int SetIV32(iv32 * iv, char * ivValue);
int SetAAD8(aad8 * aad, char * aadValue);
int SetAAD16(aad16 * aad, char * aadValue);
int SetAAD32(aad32 * aad, char * aadValue);
int SetTAG8(tag8 * tag, char * tagValue);
int SetTAG16(tag16 * tag, char * tagValue);
int OpenFile(FILE ** handler, char * name, char * mode);
int ReadFile(FILE * handler, unsigned char ** buffer, int regsize, int blocking, int * bytesread);
int WriteFile(FILE * handler, unsigned char * buffer, int regsize, int blocking, int * byteswritten);
int CloseFile(FILE * handler);
int DisplayChs(unsigned char * buffer, int size);
int PrintChs(FILE * handler, unsigned char * buffer, int size, int flag); // flag = 0 => don't DisplayChs
int DisplayNibbles(unsigned char * buffer, int size);
int DisplayHex(unsigned char * buffer, int size);
int PrintHex(FILE * handler, unsigned char * buffer, int size, int flag); // flag = 0 => don't DisplayHex
int Generate_Key128 (key128 *k) ;
int Generate_Key192 (key192 *k) ;
int Generate_Key256 (key256 *k) ;
int Generate_Nonce8 (iv8 *iv) ;
int Generate_Nonce16 (iv16 *iv) ;
int Generate_Nonce32 (iv32 *iv) ;
#endif /* ETSS_H_ */
请注意,此处不会生成十六进制代码,只需手动设置即可。
再次感谢。
答案 0 :(得分:1)
在AEAD算法中,加密缓冲区包含标记。这就是CRYPT_SIZE
比PLAIN_SIZE
长8个字节的原因。我相信你正试图解密完整的密码缓冲区,包括标签。
在Decrypta()
函数中,请仅针对mbedtls_cipher_update()
字节尝试CRYPT_SIZE - tag.size
循环
之后,从密码缓冲区中获取标记,并将其用于mbedtls_cipher_check_tag()
函数。