MbedTLS GCM解密错误

时间:2018-02-23 02:55:20

标签: encryption google-cloud-messaging mbedtls

我有下面的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_ */

请注意,此处不会生成十六进制代码,只需手动设置即可。

再次感谢。

1 个答案:

答案 0 :(得分:1)

在AEAD算法中,加密缓冲区包含标记。这就是CRYPT_SIZEPLAIN_SIZE长8个字节的原因。我相信你正试图解密完整的密码缓冲区,包括标签。 在Decrypta()函数中,请仅针对mbedtls_cipher_update()字节尝试CRYPT_SIZE - tag.size循环 之后,从密码缓冲区中获取标记,并将其用于mbedtls_cipher_check_tag()函数。