static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn, const unsigned char *iv,int in, const unsigned char *plaintext,int pn, const unsigned char *ciphertext,int cn, int encdec) { EVP_CIPHER_CTX ctx; unsigned char out[4096]; int outl,outl2; printf("Testing cipher %s%s\n",EVP_CIPHER_name(c), (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)"))); hexdump(stdout,"Key",key,kn); if(in) hexdump(stdout,"IV",iv,in); hexdump(stdout,"Plaintext",plaintext,pn); hexdump(stdout,"Ciphertext",ciphertext,cn); if(kn != c->key_len) { fprintf(stderr,"Key length doesn't match, got %d expected %d\n",kn, c->key_len); test1_exit(5); } EVP_CIPHER_CTX_init(&ctx); if (encdec != 0) { if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } EVP_CIPHER_CTX_set_padding(&ctx,0); if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn)) { fprintf(stderr,"Encrypt failed\n"); ERR_print_errors_fp(stderr); test1_exit(6); } if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2)) { fprintf(stderr,"EncryptFinal failed\n"); ERR_print_errors_fp(stderr); test1_exit(7); } if(outl+outl2 != cn) { fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n", outl+outl2,cn); test1_exit(8); } if(memcmp(out,ciphertext,cn)) { fprintf(stderr,"Ciphertext mismatch\n"); hexdump(stderr,"Got",out,cn); hexdump(stderr,"Expected",ciphertext,cn); test1_exit(9); } } if (encdec <= 0) { if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv)) { fprintf(stderr,"DecryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } EVP_CIPHER_CTX_set_padding(&ctx,0); if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn)) { fprintf(stderr,"Decrypt failed\n"); ERR_print_errors_fp(stderr); test1_exit(6); } if(!EVP_DecryptFinal_ex(&ctx,out+outl,&outl2)) { fprintf(stderr,"DecryptFinal failed\n"); ERR_print_errors_fp(stderr); test1_exit(7); } if(outl+outl2 != cn) { fprintf(stderr,"Plaintext length mismatch got %d expected %d\n", outl+outl2,cn); test1_exit(8); } if(memcmp(out,plaintext,cn)) { fprintf(stderr,"Plaintext mismatch\n"); hexdump(stderr,"Got",out,cn); hexdump(stderr,"Expected",plaintext,cn); test1_exit(9); } } EVP_CIPHER_CTX_cleanup(&ctx); printf("\n"); }
static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn, const unsigned char *iv,int in, const unsigned char *plaintext,int pn, const unsigned char *ciphertext,int cn, const unsigned char *aad,int an, const unsigned char *tag,int tn, int encdec) { EVP_CIPHER_CTX ctx; unsigned char out[4096]; int outl,outl2,mode; printf("Testing cipher %s%s\n",EVP_CIPHER_name(c), (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)"))); hexdump(stdout,"Key",key,kn); if(in) hexdump(stdout,"IV",iv,in); hexdump(stdout,"Plaintext",plaintext,pn); hexdump(stdout,"Ciphertext",ciphertext,cn); if (an) hexdump(stdout,"AAD",aad,an); if (tn) hexdump(stdout,"Tag",tag,tn); mode = EVP_CIPHER_mode(c); if(kn != EVP_CIPHER_key_length(c)) { fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn, (unsigned long)EVP_CIPHER_key_length(c)); test1_exit(5); } EVP_CIPHER_CTX_init(&ctx); if (encdec != 0) { if (mode == EVP_CIPH_GCM_MODE) { if(!EVP_EncryptInit_ex(&ctx,c,NULL,NULL,NULL)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { fprintf(stderr,"IV length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_EncryptInit_ex(&ctx,NULL,NULL,key,iv)) { fprintf(stderr,"Key/IV set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (an && !EVP_EncryptUpdate(&ctx,NULL,&outl,aad,an)) { fprintf(stderr,"AAD set failed\n"); ERR_print_errors_fp(stderr); test1_exit(13); } } else if (mode == EVP_CIPH_CCM_MODE) { if(!EVP_EncryptInit_ex(&ctx,c,NULL,NULL,NULL)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { fprintf(stderr,"IV length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, tn, NULL)) { fprintf(stderr,"Tag length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_EncryptInit_ex(&ctx,NULL,NULL,key,iv)) { fprintf(stderr,"Key/IV set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (!EVP_EncryptUpdate(&ctx,NULL,&outl,NULL,pn)) { fprintf(stderr,"Plaintext length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (an && !EVP_EncryptUpdate(&ctx,NULL,&outl,aad,an)) { fprintf(stderr,"AAD set failed\n"); ERR_print_errors_fp(stderr); test1_exit(13); } } else if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } EVP_CIPHER_CTX_set_padding(&ctx,0); if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn)) { fprintf(stderr,"Encrypt failed\n"); ERR_print_errors_fp(stderr); test1_exit(6); } if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2)) { fprintf(stderr,"EncryptFinal failed\n"); ERR_print_errors_fp(stderr); test1_exit(7); } if(outl+outl2 != cn) { fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n", outl+outl2,cn); test1_exit(8); } if(memcmp(out,ciphertext,cn)) { fprintf(stderr,"Ciphertext mismatch\n"); hexdump(stderr,"Got",out,cn); hexdump(stderr,"Expected",ciphertext,cn); test1_exit(9); } if (mode == EVP_CIPH_GCM_MODE || mode == EVP_CIPH_CCM_MODE) { unsigned char rtag[16]; /* Note: EVP_CTRL_CCM_GET_TAG has same value as * EVP_CTRL_GCM_GET_TAG */ if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tn, rtag)) { fprintf(stderr,"Get tag failed\n"); ERR_print_errors_fp(stderr); test1_exit(14); } if (memcmp(rtag, tag, tn)) { fprintf(stderr,"Tag mismatch\n"); hexdump(stderr,"Got",rtag,tn); hexdump(stderr,"Expected",tag,tn); test1_exit(9); } } } if (encdec <= 0) { if (mode == EVP_CIPH_GCM_MODE) { if(!EVP_DecryptInit_ex(&ctx,c,NULL,NULL,NULL)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { fprintf(stderr,"IV length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_DecryptInit_ex(&ctx,NULL,NULL,key,iv)) { fprintf(stderr,"Key/IV set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, tn, (void *)tag)) { fprintf(stderr,"Set tag failed\n"); ERR_print_errors_fp(stderr); test1_exit(14); } if (an && !EVP_DecryptUpdate(&ctx,NULL,&outl,aad,an)) { fprintf(stderr,"AAD set failed\n"); ERR_print_errors_fp(stderr); test1_exit(13); } } else if (mode == EVP_CIPH_CCM_MODE) { if(!EVP_DecryptInit_ex(&ctx,c,NULL,NULL,NULL)) { fprintf(stderr,"DecryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { fprintf(stderr,"IV length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, tn, (void *)tag)) { fprintf(stderr,"Tag length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_DecryptInit_ex(&ctx,NULL,NULL,key,iv)) { fprintf(stderr,"Key/Nonce set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (!EVP_DecryptUpdate(&ctx,NULL,&outl,NULL,pn)) { fprintf(stderr,"Plaintext length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (an && !EVP_EncryptUpdate(&ctx,NULL,&outl,aad,an)) { fprintf(stderr,"AAD set failed\n"); ERR_print_errors_fp(stderr); test1_exit(13); } } else if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv)) { fprintf(stderr,"DecryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } EVP_CIPHER_CTX_set_padding(&ctx,0); if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn)) { fprintf(stderr,"Decrypt failed\n"); ERR_print_errors_fp(stderr); test1_exit(6); } if(mode != EVP_CIPH_CCM_MODE && !EVP_DecryptFinal_ex(&ctx,out+outl,&outl2)) { fprintf(stderr,"DecryptFinal failed\n"); ERR_print_errors_fp(stderr); test1_exit(7); } if(outl+outl2 != pn) { fprintf(stderr,"Plaintext length mismatch got %d expected %d\n", outl+outl2,pn); test1_exit(8); } if(memcmp(out,plaintext,pn)) { fprintf(stderr,"Plaintext mismatch\n"); hexdump(stderr,"Got",out,pn); hexdump(stderr,"Expected",plaintext,pn); test1_exit(9); } } EVP_CIPHER_CTX_cleanup(&ctx); printf("\n"); }