/* ** Copyright 2004 Hewlett-Packard Development Company, L.P. ** ** Confidential computer software. Valid license from HP and/or its ** subsidiaries required for possession, use, or copying. ** ** Consistent with FAR 12.211 and 12.212, Commercial Computer Software, ** Computer Software Documentation, and Technical Data for Commercial ** Items are licensed to the U.S. Government under vendor's standard ** commercial license. ** ** Neither HP nor any of its subsidiaries shall be liable for technical ** or editorial errors or omissions contained herein. The information ** in this document is provided "as is" without warranty of any kind ** and is subject to change without notice. The warranties for HP ** products are set forth in the express limited warranty statements ** accompanying such products. Nothing herein should be construed as ** constituting an additional warranty. ** **++ ** FACILITY: ** ** SSL$EXAMPLES:SSL$AES.C ** ** ABSTRACT: ** ** This example uses SSL Advanced Encryption Standard (AES) 256 bit key ** encryption application program interface calls to encrypt 79 ** characters of data, writing the encrypted data to file, then ** decrypting the data and writing the plain text to a file. The files ** are then dumped or typed as appropriate. ** ** This exmaple demonstrates the 16 byte data block length and the ** data padding that occurs by default to pad the data to the 16 byte, ** 128 bit, data block length. Padding can be disabled with the SSL API: ** ** EVP_CIPHER_CTX_set_padding() ** ** Change the following calls for DES encryption/decryption. Note DES uses ** 8 byte, 64 bit data block sizes and pads the data accordingly: ** ** status = EVP_EncryptInit_ex( &ctx , ** // EVP_aes_256_cbc() , ** EVP_des_cbc() , ** ** status = EVP_DecryptInit_ex( &ctx , ** // EVP_aes_256_cbc(), ** EVP_des_cbc() , ** ** ** ** ** Refer to 'Build Configuration and Run Instructions' for details ** on how to build and run this program. ** ** ENVIRONMENT: (Minimal Versions) ** ** OpenVMS V8.2 Alpha, Itanium or VAX ** TCP/IP Services V5.5 ** SSL for OpenVMS V1.2 ** ** AUTHOR: ** ** OpenVMS Engineering Security Group, CREATION DATE: 13-July-2004 ** ** MODIFICATION HISTORY: ** ** **-- */ /* Build, Configuration, and Run Instructions */ /* ** BUILD INSTRUCTIONS: ** ** To build this example program use commands of the form, ** using the "DECC" compiler: ** ** To Create a 32-bit Application Using 32-bit SSL APIs ** ---------------------------------------------------- ** ** $ CC /POINTER=32 /PREFIX=ALL SSL$AES.C [/DEFINE=DO_DES] ** $ LINK SSL$AES.OBJ , SYS$INPUT:/OPT ** SYS$LIBRARY:SSL$LIBCRYPTO_SHR32.EXE /SHARE ** SYS$LIBRARY:SSL$LIBSSL_SHR32.EXE /SHARE ** $ ^z ** ** To Create a 64-bit Application Using 64-bit SSL APIs ** ---------------------------------------------------- ** ** $ CC /POINTER=64 /PREFIX=ALL SSL$AES.C [/DEFINE=DO_DES] ** $ LINK SSL$AES.OBJ , SYS$INPUT:/OPT ** SYS$LIBRARY:SSL$LIBCRYPTO_SHR.EXE /SHARE ** SYS$LIBRARY:SSL$LIBSSL_SHR.EXE /SHARE ** $ ^z ** ** Note: DEFINE DO_DES to modify the source code to use DES 56 bit ** encryption and decryption. You can also specify the following when ** compiling: ** ** /DEFINE=DO_DES ** ** CONFIGURATION INSTRUCTIONS: ** ** TCPIP and SSL must be installed and started. ** ** RUN INSTRUCTIONS: ** ** To run this example program: ** ** $ run SSL$AES.EXE */ /* ** INCLUDE FILES: */ #include "SSL$EXAMPLES:SSL_EXAMPLES.H" #include "SSL$INCLUDE:EVP.H" /* ** To use DES instead of AES encryption/decryption, ** define the following ** ** #define DO_DES ** ** or compile with ** ** $ CC /DEFINE=DO_DES ** */ #define CIPHERFILE "TEST.ENC" #define TXTFILE "TEST.DEC" /* ** Global data */ char plaintext[79] = "1234567890123456789012345678901234567890123456789012345678901234567890123456789"; unsigned char txtbuf[sizeof(plaintext)+256] = {0}; unsigned char encbuf[sizeof(plaintext)+256] = {0}; #ifndef DO_DES /* ** AES = 16 byte data blocks, initial vector, ** and AES_256 = 32 byte key */ unsigned char iv[16] = {""}; const unsigned char key[] = {"This is my simple encryption key"}; #else /* ** DES = 8 byte data blocks, initial vector, ** and a 56 bit + 8 bit parity = 8 byte key */ unsigned char iv[8] = {""}; const unsigned char key[] = {"Eightkey"}; #endif int main( void ) { int status; unsigned char * plaintext_ptr = NULL; int plaintext_len = 0; unsigned char * ciphertext_ptr = NULL; int ciphertext_len = 0; int outlen = 0; char aesfile[] = CIPHERFILE ; char textfile[] = TXTFILE ; FILE *AFILE; int oLen = 0; EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX *ctx_ptr = &ctx; /* ** The following six functions are obsolete but are retained for compatibility ** with existing code: ** ** EVP_EncryptInit(), EVP_EncryptFinal(), ** EVP_DecryptInit(), EVP_DecryptFinal(), ** EVP_CipherInit() and EVP_CipherFinal(). ** ** New code should use the following new calls as they can reuse an ** existing context without allocating and freeing it up on each call: ** ** EVP_EncryptInit_ex(), EVP_EncryptFinal_ex(), ** EVP_DecryptInit_ex(), EVP_DecryptFinal_ex(), ** EVP_CipherInit_ex() and EVP_CipherFinal_ex() */ EVP_CIPHER_CTX_init( ctx_ptr ); /***************** Encryption First *************************************************/ plaintext_ptr = (unsigned char *) plaintext ; plaintext_len = sizeof( plaintext ); ciphertext_ptr = encbuf; /* Use encbuf for cipher text */ ciphertext_len = sizeof (encbuf); status = EVP_EncryptInit_ex( &ctx , #ifndef DO_DES EVP_aes_256_cbc() , #else EVP_des_cbc() , #endif NULL , key , iv ); check_vms( status , "\n\t !!! EVP_EncryptInit_ex() Failure !!! \n"); /* ** Uncomment the following call after initialization to ** disable padding of data blocks. ** ** NOTE: ** You must ensure that 'plaintext' is an exact multiple of ** an AES 16 byte, 128 bit data block (8 bytes, 64 bits = DES), ** or else EVP_EncryptFinal_ex() or EVP_DecryptFinal_ex() will ** fail. ** ** EVP_CIPHER_CTX_set_padding( ctx_ptr , 0); ** */ status = EVP_EncryptUpdate( &ctx , ciphertext_ptr , &outlen , plaintext_ptr , plaintext_len ); check_vms( status , "\n\t !!! EVP_EncryptUpdate() Failure !!! \n"); printf ("EncryptUpdate() writes %d bytes \n", outlen ); ciphertext_ptr += outlen; /* Adjust O/P buffer pointer */ ciphertext_len = outlen; /* Initial encryption */ status = EVP_EncryptFinal_ex( &ctx , ciphertext_ptr , &outlen ); check_vms( status , "\n\t !!! EVP_EncryptFinal_ex() Failure !!! \n"); printf ("EncryptFinal_ex() writes %d bytes \n", outlen ); ciphertext_len += outlen ; /* Total encryption with padding */ AFILE = fopen( CIPHERFILE , "wb"); fwrite ( encbuf , 1, ciphertext_len , AFILE ); fclose (AFILE); /************************ Decryption Next *************************************************/ plaintext_ptr = txtbuf ; /* Use txtbuf for plain text output */ plaintext_len = sizeof(txtbuf); ciphertext_ptr = encbuf ; status = EVP_DecryptInit_ex( &ctx , #ifndef DO_DES EVP_aes_256_cbc(), #else EVP_des_cbc() , #endif NULL , key , iv ); check_vms( status , "\n\t !!! EVP_DecryptInit_ex() Failure !!! \n"); /* ** Uncomment the following call after initialization to ** disable padding of data blocks. ** ** NOTE: ** You must ensure that 'plaintext' is an exact multiple of ** an AES 16 byte, 128 bit data block (8 bytes, 64 bits = DES), ** or else EVP_EncryptFinal_ex() or EVP_DecryptFinal_ex() will ** fail. ** ** EVP_CIPHER_CTX_set_padding( ctx_ptr , 0); ** */ status = EVP_DecryptUpdate( &ctx , plaintext_ptr , &outlen , ciphertext_ptr , ciphertext_len ); check_vms( status , "\n\t !!! EVP_DecryptUpdate() Failure !!! \n"); printf ("DecryptUpdate() writes %d bytes \n", outlen); plaintext_len = outlen; /* Initial decryption */ plaintext_ptr += outlen; /* adjust decrypted O/P buffer */ status = EVP_DecryptFinal_ex( &ctx , plaintext_ptr , &outlen ); check_vms( status , "\n\t !!! EVP_DecryptFinal_ex() Failure !!! \n"); printf ("DecryptFinal_ex() writes %d bytes \n", outlen ); plaintext_len += outlen ; /* Total decryption with padding */ plaintext_ptr += outlen; /* adjust decrypted O/P buffer */ *plaintext_ptr='\0'; /* terminate string at data's end */ printf("Decrypted value is: \n%s \n", txtbuf ); AFILE = fopen( TXTFILE , "wb"); fwrite ( txtbuf , 1, plaintext_len , AFILE ); fclose (AFILE); EVP_CIPHER_CTX_cleanup( ctx_ptr ); system("directory /date=creat TEST.ENC; "); check_vms( status , "\n\t !!! DIRECTORY Command Failure !!! \n"); system("dump TEST.ENC;"); check_vms( status , "\n\t !!! DUMP Command Failure !!! \n"); system("directory /date=creat TEST.DEC; "); check_vms( status , "\n\t !!! DIRECTORY Command Failure !!! \n"); system("type TEST.DEC;"); check_vms( status , "\n\t !!! TYPE Command Failure !!! \n"); return( status ); }