阅读背景:

openssl编程-aead_lanzh_

来源:互联网 

一、openssl aead算法接口使用示例:

//gcc -g -lssl aead_test.c -lcrypto -L /usr/local/lib/
#include <string.h>
#include <openssl/evp.h>

#define IV_SIZE 8
#define KEY_SIZE 24
#define INPUT_SIZE 100

void print_hexdata(unsigned char *b, int len, char *title) 
{
	int i = 0, c = 0;
	printf("===================================== %s =====================================\n", title);
	for (; i<len; i++) {
		printf("0x%02x ", b[i]);
		c++;
		if (!(c%16))
			printf("\n");
	}
	printf("\n");
}

int gcm_encrypt(unsigned char *plaintext, int plaintext_len,
                unsigned char *aad, int aad_len,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *ciphertext,
                unsigned char *tag)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int ciphertext_len;


    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the encryption operation. */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /*
     * Set IV length if default 12 bytes (96 bits) is not appropriate
     */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;
	printf("len:%d\n", len);
    /*
     * Provide the message to be encrypted, and obtain the encrypted output.
     * EVP_EncryptUpdate can be called multiple times if necessary
     */
    if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        return -1;
    ciphertext_len = len;
	printf("len:%d\n", len);

    /*
     * Finalise the encryption. Normally ciphertext bytes may be written at
     * this stage, but this does not occur in GCM mode
     */
    if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
        return -1;
    ciphertext_len += len;
	printf("len:%d\n", len);

    /* Get the tag */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
        return -1;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len,
                unsigned char *aad, int aad_len,
                unsigned char *tag,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *plaintext)
{
    EVP_CIPHER_CTX *ctx;
    int len;
    int plaintext_len;
    int ret;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the decryption operation. */
    if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /* Set IV length. Not necessary if this is 12 bytes (96 bits) */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;

    /*
     * Provide the message to be decrypted, and obtain the plaintext output.
     * EVP_DecryptUpdate can be called multiple times if necessary
     */
    if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        return -1;
    plaintext_len = len;
	printf("len:%d\n", len);

    /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
        return -1;

    /*
     * Finalise the decryption. A positive return value indicates success,
     * anything else is a failure - the plaintext is not trustworthy.
     */
    ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
	printf("len:%d\n", len);

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    if(ret > 0) {
        /* Success */
        plaintext_len += len;
        return plaintext_len;
    } else {
        /* Verify failed */
        return -1;
    }
}

int main()
{
	unsigned char plaintext[16] = "aaaabbbbccccdddd";
	unsigned char add[16] = "aaaabbbbccccdddd";
	unsigned char key[16] = "aaaabbbbccccdddd";
	unsigned char iv[16] = "aaaabbbbccccdddd";
	unsigned char ciphertext[16] = "

一、openssl aead算法接口使用示例:

//gcc -g -lssl aead_test.c -lcrypto -L /usr/local/lib/
#include <string.h>
#include <openssl/evp.h>

#define IV_SIZE 8
#define KEY_SIZE 24
#define INPUT_SIZE 100

void print_hexdata(unsigned char *b, int len, char *title) 
{
	int i = 0, c = 0;
	printf("===================================== %s =====================================\n", title);
	for (; i<len; i++) {
		printf("0x%02x ", b[i]);
		c++;
		if (!(c%16))
			printf("\n");
	}
	printf("\n");
}

int gcm_encrypt(unsigned char *plaintext, int plaintext_len,
                unsigned char *aad, int aad_len,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *ciphertext,
                unsigned char *tag)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int ciphertext_len;


    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the encryption operation. */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /*
     * Set IV length if default 12 bytes (96 bits) is not appropriate
     */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;
	printf("len:%d\n", len);
    /*
     * Provide the message to be encrypted, and obtain the encrypted output.
     * EVP_EncryptUpdate can be called multiple times if necessary
     */
    if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        return -1;
    ciphertext_len = len;
	printf("len:%d\n", len);

    /*
     * Finalise the encryption. Normally ciphertext bytes may be written at
     * this stage, but this does not occur in GCM mode
     */
    if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
        return -1;
    ciphertext_len += len;
	printf("len:%d\n", len);

    /* Get the tag */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
        return -1;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len,
                unsigned char *aad, int aad_len,
                unsigned char *tag,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *plaintext)
{
    EVP_CIPHER_CTX *ctx;
    int len;
    int plaintext_len;
    int ret;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the decryption operation. */
    if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /* Set IV length. Not necessary if this is 12 bytes (96 bits) */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;

    /*
     * Provide the message to be decrypted, and obtain the plaintext output.
     * EVP_DecryptUpdate can be called multiple times if necessary
     */
    if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        return -1;
    plaintext_len = len;
	printf("len:%d\n", len);

    /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
        return -1;

    /*
     * Finalise the decryption. A positive return value indicates success,
     * anything else is a failure - the plaintext is not trustworthy.
     */
    ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
	printf("len:%d\n", len);

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    if(ret > 0) {
        /* Success */
        plaintext_len += len;
        return plaintext_len;
    } else {
        /* Verify failed */
        return -1;
    }
}

int main()
{
	unsigned char plaintext[16] = "aaaabbbbccccdddd";
	unsigned char add[16] = "aaaabbbbccccdddd";
	unsigned char key[16] = "aaaabbbbccccdddd";
	unsigned char iv[16] = "aaaabbbbccccdddd";
	unsigned char ciphertext[16] = "\0";
	unsigned char tag[16] = "\0";
	unsigned char de_plaintext[16] = "\0";
	
	gcm_encrypt(plaintext, 16, add, 16, key, iv, 16, ciphertext, tag);
	
	print_hexdata(plaintext, 16, "plaintext");
	print_hexdata(add, 16, "add");
	print_hexdata(key, 16, "key");
	print_hexdata(iv, 16, "iv");
	print_hexdata(ciphertext, 16, "ciphertext");
	print_hexdata(tag, 16, "tag");
		
	gcm_decrypt(ciphertext, 16, add, 16, tag, key, iv, 16, de_plaintext);
	
	print_hexdata(de_plaintext, 16, "de_plaintext");
	
	
	printf("test ok\n");
	return 0;
}

二、使用一组协议数据进行算法验证:

//gcc -g -lssl aead_test.c -lcrypto -L /usr/local/lib/
#include <string.h>
#include <openssl/evp.h>

struct aead_testvec {
	const char *key;
	const char *iv;
	const char *ptext;
	const char *assoc;
	const char *ctext;
	unsigned char novrfy;
	unsigned char wk;
	unsigned char klen;
	unsigned int plen;
	unsigned int clen;
	unsigned int alen;
	int setkey_error;
	int setauthsize_error;
	int crypt_error;
};

/* 256bit */
struct aead_testvec aes_gcm_tv_template_256[] = {
	{
	.key	= "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
		  "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
	.klen	= 32,
	.iv	= "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
		  "\xde\xca\xf8\x88",
	.ptext	= "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
		  "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
		  "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
		  "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
		  "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
		  "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
		  "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
		  "\xba\x63\x7b\x39",
	.plen	= 60,
	.assoc	= "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xab\xad\xda\xd2",
	.alen	= 20,
	.ctext	= "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
		  "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
		  "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
		  "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
		  "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
		  "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
		  "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
		  "\xbc\xc9\xf6\x62"
		  "\x76\xfc\x6e\xce\x0f\x4e\x17\x68"
		  "\xcd\xdf\x88\x53\xbb\x2d\x55\x1b",
	.clen	= 76,
	}
};

void print_hexdata(unsigned char *b, int len, char *title) 
{
	int i = 0, c = 0;
	printf("===================================== %s =====================================\n", title);
	for (; i<len; i++) {
		printf("0x%02x ", b[i]);
		c++;
		if (!(c%16))
			printf("\n");
	}
	printf("\n");
}

int gcm_encrypt(unsigned char *plaintext, int plaintext_len,
                unsigned char *aad, int aad_len,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *ciphertext,
                unsigned char *tag)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int ciphertext_len;


    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the encryption operation. */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /*
     * Set IV length if default 12 bytes (96 bits) is not appropriate
     */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;
	printf("len:%d\n", len);
    /*
     * Provide the message to be encrypted, and obtain the encrypted output.
     * EVP_EncryptUpdate can be called multiple times if necessary
     */
    if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        return -1;
    ciphertext_len = len;
	printf("len:%d\n", len);

    /*
     * Finalise the encryption. Normally ciphertext bytes may be written at
     * this stage, but this does not occur in GCM mode
     */
    if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
        return -1;
    ciphertext_len += len;
	printf("len:%d\n", len);

    /* Get the tag */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
        return -1;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len,
                unsigned char *aad, int aad_len,
                unsigned char *tag,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *plaintext)
{
    EVP_CIPHER_CTX *ctx;
    int len;
    int plaintext_len;
    int ret;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the decryption operation. */
    if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /* Set IV length. Not necessary if this is 12 bytes (96 bits) */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;

    /*
     * Provide the message to be decrypted, and obtain the plaintext output.
     * EVP_DecryptUpdate can be called multiple times if necessary
     */
    if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        return -1;
    plaintext_len = len;
	printf("len:%d\n", len);

    /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
        return -1;

    /*
     * Finalise the decryption. A positive return value indicates success,
     * anything else is a failure - the plaintext is not trustworthy.
     */
    ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
	printf("len:%d\n", len);

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    if(ret > 0) {
        /* Success */
        plaintext_len += len;
        return plaintext_len;
    } else {
        /* Verify failed */
        return -1;
    }
}

int main()
{
	unsigned char plaintext[60] = 
		  "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
		  "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
		  "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
		  "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
		  "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
		  "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
		  "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
		  "\xba\x63\x7b\x39";
	unsigned char add[20] = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xab\xad\xda\xd2";
	unsigned char key[32] = 
		  "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
		  "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08";
	unsigned char iv[12] = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
		  "\xde\xca\xf8\x88";
	unsigned char ciphertext[60] = "\0";
	unsigned char tag[16] = "\0";
	unsigned char de_plaintext[60] = "\0";
	
	gcm_encrypt(plaintext, 60, add, 20, key, iv, 12, ciphertext, tag);
	
	print_hexdata(plaintext, 60, "plaintext");
	print_hexdata(add, 20, "add");
	print_hexdata(key, 32, "key");
	print_hexdata(iv, 12, "iv");
	print_hexdata(ciphertext, 60, "ciphertext");
	print_hexdata(tag, 16, "tag");
	
	gcm_decrypt(ciphertext, 60, add, 20, tag1, key, iv, 12, de_plaintext);
	
	print_hexdata(de_plaintext, 60, "de_plaintext");
	
	
	printf("test ok\n");
	return 0;
}

 


"; unsigned char tag[16] = "

一、openssl aead算法接口使用示例:

//gcc -g -lssl aead_test.c -lcrypto -L /usr/local/lib/
#include <string.h>
#include <openssl/evp.h>

#define IV_SIZE 8
#define KEY_SIZE 24
#define INPUT_SIZE 100

void print_hexdata(unsigned char *b, int len, char *title) 
{
	int i = 0, c = 0;
	printf("===================================== %s =====================================\n", title);
	for (; i<len; i++) {
		printf("0x%02x ", b[i]);
		c++;
		if (!(c%16))
			printf("\n");
	}
	printf("\n");
}

int gcm_encrypt(unsigned char *plaintext, int plaintext_len,
                unsigned char *aad, int aad_len,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *ciphertext,
                unsigned char *tag)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int ciphertext_len;


    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the encryption operation. */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /*
     * Set IV length if default 12 bytes (96 bits) is not appropriate
     */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;
	printf("len:%d\n", len);
    /*
     * Provide the message to be encrypted, and obtain the encrypted output.
     * EVP_EncryptUpdate can be called multiple times if necessary
     */
    if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        return -1;
    ciphertext_len = len;
	printf("len:%d\n", len);

    /*
     * Finalise the encryption. Normally ciphertext bytes may be written at
     * this stage, but this does not occur in GCM mode
     */
    if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
        return -1;
    ciphertext_len += len;
	printf("len:%d\n", len);

    /* Get the tag */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
        return -1;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len,
                unsigned char *aad, int aad_len,
                unsigned char *tag,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *plaintext)
{
    EVP_CIPHER_CTX *ctx;
    int len;
    int plaintext_len;
    int ret;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the decryption operation. */
    if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /* Set IV length. Not necessary if this is 12 bytes (96 bits) */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;

    /*
     * Provide the message to be decrypted, and obtain the plaintext output.
     * EVP_DecryptUpdate can be called multiple times if necessary
     */
    if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        return -1;
    plaintext_len = len;
	printf("len:%d\n", len);

    /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
        return -1;

    /*
     * Finalise the decryption. A positive return value indicates success,
     * anything else is a failure - the plaintext is not trustworthy.
     */
    ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
	printf("len:%d\n", len);

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    if(ret > 0) {
        /* Success */
        plaintext_len += len;
        return plaintext_len;
    } else {
        /* Verify failed */
        return -1;
    }
}

int main()
{
	unsigned char plaintext[16] = "aaaabbbbccccdddd";
	unsigned char add[16] = "aaaabbbbccccdddd";
	unsigned char key[16] = "aaaabbbbccccdddd";
	unsigned char iv[16] = "aaaabbbbccccdddd";
	unsigned char ciphertext[16] = "\0";
	unsigned char tag[16] = "\0";
	unsigned char de_plaintext[16] = "\0";
	
	gcm_encrypt(plaintext, 16, add, 16, key, iv, 16, ciphertext, tag);
	
	print_hexdata(plaintext, 16, "plaintext");
	print_hexdata(add, 16, "add");
	print_hexdata(key, 16, "key");
	print_hexdata(iv, 16, "iv");
	print_hexdata(ciphertext, 16, "ciphertext");
	print_hexdata(tag, 16, "tag");
		
	gcm_decrypt(ciphertext, 16, add, 16, tag, key, iv, 16, de_plaintext);
	
	print_hexdata(de_plaintext, 16, "de_plaintext");
	
	
	printf("test ok\n");
	return 0;
}

二、使用一组协议数据进行算法验证:

//gcc -g -lssl aead_test.c -lcrypto -L /usr/local/lib/
#include <string.h>
#include <openssl/evp.h>

struct aead_testvec {
	const char *key;
	const char *iv;
	const char *ptext;
	const char *assoc;
	const char *ctext;
	unsigned char novrfy;
	unsigned char wk;
	unsigned char klen;
	unsigned int plen;
	unsigned int clen;
	unsigned int alen;
	int setkey_error;
	int setauthsize_error;
	int crypt_error;
};

/* 256bit */
struct aead_testvec aes_gcm_tv_template_256[] = {
	{
	.key	= "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
		  "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
	.klen	= 32,
	.iv	= "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
		  "\xde\xca\xf8\x88",
	.ptext	= "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
		  "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
		  "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
		  "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
		  "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
		  "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
		  "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
		  "\xba\x63\x7b\x39",
	.plen	= 60,
	.assoc	= "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xab\xad\xda\xd2",
	.alen	= 20,
	.ctext	= "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
		  "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
		  "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
		  "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
		  "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
		  "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
		  "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
		  "\xbc\xc9\xf6\x62"
		  "\x76\xfc\x6e\xce\x0f\x4e\x17\x68"
		  "\xcd\xdf\x88\x53\xbb\x2d\x55\x1b",
	.clen	= 76,
	}
};

void print_hexdata(unsigned char *b, int len, char *title) 
{
	int i = 0, c = 0;
	printf("===================================== %s =====================================\n", title);
	for (; i<len; i++) {
		printf("0x%02x ", b[i]);
		c++;
		if (!(c%16))
			printf("\n");
	}
	printf("\n");
}

int gcm_encrypt(unsigned char *plaintext, int plaintext_len,
                unsigned char *aad, int aad_len,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *ciphertext,
                unsigned char *tag)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int ciphertext_len;


    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the encryption operation. */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /*
     * Set IV length if default 12 bytes (96 bits) is not appropriate
     */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;
	printf("len:%d\n", len);
    /*
     * Provide the message to be encrypted, and obtain the encrypted output.
     * EVP_EncryptUpdate can be called multiple times if necessary
     */
    if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        return -1;
    ciphertext_len = len;
	printf("len:%d\n", len);

    /*
     * Finalise the encryption. Normally ciphertext bytes may be written at
     * this stage, but this does not occur in GCM mode
     */
    if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
        return -1;
    ciphertext_len += len;
	printf("len:%d\n", len);

    /* Get the tag */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
        return -1;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len,
                unsigned char *aad, int aad_len,
                unsigned char *tag,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *plaintext)
{
    EVP_CIPHER_CTX *ctx;
    int len;
    int plaintext_len;
    int ret;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the decryption operation. */
    if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /* Set IV length. Not necessary if this is 12 bytes (96 bits) */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;

    /*
     * Provide the message to be decrypted, and obtain the plaintext output.
     * EVP_DecryptUpdate can be called multiple times if necessary
     */
    if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        return -1;
    plaintext_len = len;
	printf("len:%d\n", len);

    /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
        return -1;

    /*
     * Finalise the decryption. A positive return value indicates success,
     * anything else is a failure - the plaintext is not trustworthy.
     */
    ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
	printf("len:%d\n", len);

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    if(ret > 0) {
        /* Success */
        plaintext_len += len;
        return plaintext_len;
    } else {
        /* Verify failed */
        return -1;
    }
}

int main()
{
	unsigned char plaintext[60] = 
		  "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
		  "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
		  "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
		  "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
		  "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
		  "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
		  "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
		  "\xba\x63\x7b\x39";
	unsigned char add[20] = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xab\xad\xda\xd2";
	unsigned char key[32] = 
		  "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
		  "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08";
	unsigned char iv[12] = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
		  "\xde\xca\xf8\x88";
	unsigned char ciphertext[60] = "\0";
	unsigned char tag[16] = "\0";
	unsigned char de_plaintext[60] = "\0";
	
	gcm_encrypt(plaintext, 60, add, 20, key, iv, 12, ciphertext, tag);
	
	print_hexdata(plaintext, 60, "plaintext");
	print_hexdata(add, 20, "add");
	print_hexdata(key, 32, "key");
	print_hexdata(iv, 12, "iv");
	print_hexdata(ciphertext, 60, "ciphertext");
	print_hexdata(tag, 16, "tag");
	
	gcm_decrypt(ciphertext, 60, add, 20, tag1, key, iv, 12, de_plaintext);
	
	print_hexdata(de_plaintext, 60, "de_plaintext");
	
	
	printf("test ok\n");
	return 0;
}

 


"; unsigned char de_plaintext[16] = "

一、openssl aead算法接口使用示例:

//gcc -g -lssl aead_test.c -lcrypto -L /usr/local/lib/
#include <string.h>
#include <openssl/evp.h>

#define IV_SIZE 8
#define KEY_SIZE 24
#define INPUT_SIZE 100

void print_hexdata(unsigned char *b, int len, char *title) 
{
	int i = 0, c = 0;
	printf("===================================== %s =====================================\n", title);
	for (; i<len; i++) {
		printf("0x%02x ", b[i]);
		c++;
		if (!(c%16))
			printf("\n");
	}
	printf("\n");
}

int gcm_encrypt(unsigned char *plaintext, int plaintext_len,
                unsigned char *aad, int aad_len,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *ciphertext,
                unsigned char *tag)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int ciphertext_len;


    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the encryption operation. */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /*
     * Set IV length if default 12 bytes (96 bits) is not appropriate
     */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;
	printf("len:%d\n", len);
    /*
     * Provide the message to be encrypted, and obtain the encrypted output.
     * EVP_EncryptUpdate can be called multiple times if necessary
     */
    if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        return -1;
    ciphertext_len = len;
	printf("len:%d\n", len);

    /*
     * Finalise the encryption. Normally ciphertext bytes may be written at
     * this stage, but this does not occur in GCM mode
     */
    if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
        return -1;
    ciphertext_len += len;
	printf("len:%d\n", len);

    /* Get the tag */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
        return -1;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len,
                unsigned char *aad, int aad_len,
                unsigned char *tag,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *plaintext)
{
    EVP_CIPHER_CTX *ctx;
    int len;
    int plaintext_len;
    int ret;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the decryption operation. */
    if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /* Set IV length. Not necessary if this is 12 bytes (96 bits) */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;

    /*
     * Provide the message to be decrypted, and obtain the plaintext output.
     * EVP_DecryptUpdate can be called multiple times if necessary
     */
    if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        return -1;
    plaintext_len = len;
	printf("len:%d\n", len);

    /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
        return -1;

    /*
     * Finalise the decryption. A positive return value indicates success,
     * anything else is a failure - the plaintext is not trustworthy.
     */
    ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
	printf("len:%d\n", len);

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    if(ret > 0) {
        /* Success */
        plaintext_len += len;
        return plaintext_len;
    } else {
        /* Verify failed */
        return -1;
    }
}

int main()
{
	unsigned char plaintext[16] = "aaaabbbbccccdddd";
	unsigned char add[16] = "aaaabbbbccccdddd";
	unsigned char key[16] = "aaaabbbbccccdddd";
	unsigned char iv[16] = "aaaabbbbccccdddd";
	unsigned char ciphertext[16] = "\0";
	unsigned char tag[16] = "\0";
	unsigned char de_plaintext[16] = "\0";
	
	gcm_encrypt(plaintext, 16, add, 16, key, iv, 16, ciphertext, tag);
	
	print_hexdata(plaintext, 16, "plaintext");
	print_hexdata(add, 16, "add");
	print_hexdata(key, 16, "key");
	print_hexdata(iv, 16, "iv");
	print_hexdata(ciphertext, 16, "ciphertext");
	print_hexdata(tag, 16, "tag");
		
	gcm_decrypt(ciphertext, 16, add, 16, tag, key, iv, 16, de_plaintext);
	
	print_hexdata(de_plaintext, 16, "de_plaintext");
	
	
	printf("test ok\n");
	return 0;
}

二、使用一组协议数据进行算法验证:

//gcc -g -lssl aead_test.c -lcrypto -L /usr/local/lib/
#include <string.h>
#include <openssl/evp.h>

struct aead_testvec {
	const char *key;
	const char *iv;
	const char *ptext;
	const char *assoc;
	const char *ctext;
	unsigned char novrfy;
	unsigned char wk;
	unsigned char klen;
	unsigned int plen;
	unsigned int clen;
	unsigned int alen;
	int setkey_error;
	int setauthsize_error;
	int crypt_error;
};

/* 256bit */
struct aead_testvec aes_gcm_tv_template_256[] = {
	{
	.key	= "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
		  "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08",
	.klen	= 32,
	.iv	= "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
		  "\xde\xca\xf8\x88",
	.ptext	= "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
		  "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
		  "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
		  "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
		  "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
		  "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
		  "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
		  "\xba\x63\x7b\x39",
	.plen	= 60,
	.assoc	= "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xab\xad\xda\xd2",
	.alen	= 20,
	.ctext	= "\x52\x2d\xc1\xf0\x99\x56\x7d\x07"
		  "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d"
		  "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9"
		  "\x75\x98\xa2\xbd\x25\x55\xd1\xaa"
		  "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d"
		  "\xa7\xb0\x8b\x10\x56\x82\x88\x38"
		  "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a"
		  "\xbc\xc9\xf6\x62"
		  "\x76\xfc\x6e\xce\x0f\x4e\x17\x68"
		  "\xcd\xdf\x88\x53\xbb\x2d\x55\x1b",
	.clen	= 76,
	}
};

void print_hexdata(unsigned char *b, int len, char *title) 
{
	int i = 0, c = 0;
	printf("===================================== %s =====================================\n", title);
	for (; i<len; i++) {
		printf("0x%02x ", b[i]);
		c++;
		if (!(c%16))
			printf("\n");
	}
	printf("\n");
}

int gcm_encrypt(unsigned char *plaintext, int plaintext_len,
                unsigned char *aad, int aad_len,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *ciphertext,
                unsigned char *tag)
{
    EVP_CIPHER_CTX *ctx;

    int len;

    int ciphertext_len;


    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the encryption operation. */
    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /*
     * Set IV length if default 12 bytes (96 bits) is not appropriate
     */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;
	printf("len:%d\n", len);
    /*
     * Provide the message to be encrypted, and obtain the encrypted output.
     * EVP_EncryptUpdate can be called multiple times if necessary
     */
    if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
        return -1;
    ciphertext_len = len;
	printf("len:%d\n", len);

    /*
     * Finalise the encryption. Normally ciphertext bytes may be written at
     * this stage, but this does not occur in GCM mode
     */
    if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
        return -1;
    ciphertext_len += len;
	printf("len:%d\n", len);

    /* Get the tag */
    if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
        return -1;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    return ciphertext_len;
}

int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len,
                unsigned char *aad, int aad_len,
                unsigned char *tag,
                unsigned char *key,
                unsigned char *iv, int iv_len,
                unsigned char *plaintext)
{
    EVP_CIPHER_CTX *ctx;
    int len;
    int plaintext_len;
    int ret;

    /* Create and initialise the context */
    if(!(ctx = EVP_CIPHER_CTX_new()))
        return -1;

    /* Initialise the decryption operation. */
    if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
        return -1;

    /* Set IV length. Not necessary if this is 12 bytes (96 bits) */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_len, NULL))
        return -1;

    /* Initialise key and IV */
    if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
        return -1;

    /*
     * Provide any AAD data. This can be called zero or more times as
     * required
     */
    if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
        return -1;

    /*
     * Provide the message to be decrypted, and obtain the plaintext output.
     * EVP_DecryptUpdate can be called multiple times if necessary
     */
    if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
        return -1;
    plaintext_len = len;
	printf("len:%d\n", len);

    /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
    if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
        return -1;

    /*
     * Finalise the decryption. A positive return value indicates success,
     * anything else is a failure - the plaintext is not trustworthy.
     */
    ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
	printf("len:%d\n", len);

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);

    if(ret > 0) {
        /* Success */
        plaintext_len += len;
        return plaintext_len;
    } else {
        /* Verify failed */
        return -1;
    }
}

int main()
{
	unsigned char plaintext[60] = 
		  "\xd9\x31\x32\x25\xf8\x84\x06\xe5"
		  "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
		  "\x86\xa7\xa9\x53\x15\x34\xf7\xda"
		  "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
		  "\x1c\x3c\x0c\x95\x95\x68\x09\x53"
		  "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
		  "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57"
		  "\xba\x63\x7b\x39";
	unsigned char add[20] = "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xfe\xed\xfa\xce\xde\xad\xbe\xef"
		  "\xab\xad\xda\xd2";
	unsigned char key[32] = 
		  "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08"
		  "\xfe\xff\xe9\x92\x86\x65\x73\x1c"
		  "\x6d\x6a\x8f\x94\x67\x30\x83\x08";
	unsigned char iv[12] = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad"
		  "\xde\xca\xf8\x88";
	unsigned char ciphertext[60] = "\0";
	unsigned char tag[16] = "\0";
	unsigned char de_plaintext[60] = "\0";
	
	gcm_encrypt(plaintext, 60, add, 20, key, iv, 12, ciphertext, tag);
	
	print_hexdata(plaintext, 60, "plaintext");
	print_hexdata(add, 20, "add");
	print_hexdata(key, 32, "key");
	print_hexdata(iv, 12, "iv");
	print_hexdata(ciphertext, 60, "ciphertext");
	print_hexdata(tag, 16, "tag");
	
	gcm_decrypt(ciphertext, 60, add, 20, tag1, key, iv, 12, de_plaintext);
	
	print_hexdata(de_plaintext, 60, "de_plaintext");
	
	
	printf("test ok\n");
	return 0;
}

 


"; gcm_encrypt(plaintext, 16, add, 16, key, iv, 16, ciphertext, tag); print_hexdata(plaintext, 16, "plaintext"); print_hexdata(add, 16, "add"); print_hexdata(key, 16, "key"); print_hexdata(iv, 16, "iv"); print_hexdata(ciphertext, 16, "ciphertext"); print_hexdata(tag, 16, "tag"); gcm_decrypt(ciphertext, 16, add, 16, tag, key, iv, 16, de_plaintext); print_hexdata(de_plaintext, 16, "de_plaintext"); printf("test ok\n"); return 0; }//gcc -g -lssl aead_t



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: