@@ -514,11 +514,134 @@ int test_aes256_ctr_stream(ENGINE *e, void *data)
514514 return err ;
515515}
516516
517- /* OpenSSL allows the user to call EVP_CipherInit with NULL key or IV. In the
517+ /*
518+ * This test exercises a bug in some versions of wolfSSL where partial block
519+ * data (i.e. data that didn't align to the AES block size of 16 bytes) from a
520+ * previous AES-CTR operation would be mixed in with the next operation's input
521+ * data, even when the IV was changed in between. When the key or IV changes,
522+ * any partial block data should not be used.
523+ */
524+ int test_aes_ctr_leftover_data_regression (ENGINE * e , void * data )
525+ {
526+ enum {
527+ NUM_PACKETS = 2 ,
528+ PACKET_SIZE = AES_BLOCK_SIZE + 1
529+ };
530+ int err = 0 ;
531+ const unsigned char key [AES_128_KEY_SIZE ] = {
532+ 0x37 , 0xe8 , 0x46 , 0x48 , 0xf4 , 0xd6 , 0xa7 , 0x28 , 0xc6 , 0xd5 , 0x2e , 0x3b ,
533+ 0xf4 , 0xc4 , 0x46 , 0x66
534+ };
535+ const unsigned char ivs [NUM_PACKETS ][AES_BLOCK_SIZE ] = {
536+ {
537+ 0x88 , 0x93 , 0x6f , 0xfd , 0x7d , 0x94 , 0x21 , 0xcc , 0x40 , 0x64 , 0xde ,
538+ 0x8a , 0xb9 , 0xaf , 0xdd , 0xe4
539+ },
540+ {
541+ 0x0f , 0x10 , 0x9c , 0xc9 , 0x25 , 0x9a , 0x53 , 0xf0 , 0xd3 , 0x92 , 0xdf ,
542+ 0x35 , 0xb2 , 0x35 , 0xa6 , 0xd8
543+ }
544+ };
545+ const unsigned char packets [NUM_PACKETS ][PACKET_SIZE ] = {
546+ {
547+ 0x3c , 0x89 , 0x18 , 0x76 , 0xfc , 0xae , 0xdc , 0xee , 0xab , 0xf2 , 0xf7 ,
548+ 0x56 , 0x47 , 0x1f , 0xe9 , 0x20 , 0x67
549+ },
550+ {
551+ 0xb5 , 0x3b , 0x8d , 0xa1 , 0xe7 , 0x0a , 0x46 , 0x56 , 0xf6 , 0xfd , 0xeb ,
552+ 0x85 , 0x61 , 0xd8 , 0xaf , 0xac , 0xfb
553+ }
554+ };
555+ EVP_CIPHER_CTX * encCtx = NULL ;
556+ EVP_CIPHER_CTX * decCtx = NULL ;
557+ unsigned char encText [PACKET_SIZE ];
558+ unsigned char decText [PACKET_SIZE ];
559+ int i ;
560+
561+ (void )data ;
562+
563+ if (err == 0 ) {
564+ err = (encCtx = EVP_CIPHER_CTX_new ()) == NULL ;
565+ }
566+ if (err == 0 ) {
567+ err = (decCtx = EVP_CIPHER_CTX_new ()) == NULL ;
568+ }
569+
570+ /* Set key. */
571+ if (err == 0 ) {
572+ err = EVP_CipherInit_ex (encCtx , EVP_aes_128_ctr (), NULL , key ,
573+ NULL , -1 ) != 1 ;
574+ }
575+ if (err == 0 ) {
576+ err = EVP_CipherInit_ex (decCtx , EVP_aes_128_ctr (), e , key ,
577+ NULL , -1 ) != 1 ;
578+ }
579+
580+ for (i = 0 ; err == 0 && i < NUM_PACKETS ; ++ i ) {
581+ /* Set IV. */
582+ if (err == 0 ) {
583+ err = EVP_CipherInit_ex (encCtx , NULL , NULL , NULL , ivs [i ], 1 ) != 1 ;
584+ }
585+ if (err == 0 ) {
586+ err = EVP_CipherInit_ex (decCtx , NULL , e , NULL , ivs [i ], 0 ) != 1 ;
587+ }
588+ /* Encrypt. */
589+ if (err == 0 ) {
590+ err = EVP_Cipher (encCtx , encText , packets [i ], PACKET_SIZE ) < 0 ;
591+ }
592+ /* Decrypt. */
593+ if (err == 0 ) {
594+ err = EVP_Cipher (decCtx , decText , encText , PACKET_SIZE ) < 0 ;
595+ }
596+ /* Ensure decrypted and plaintext match. */
597+ if (err == 0 ) {
598+ err = memcmp (decText , packets [i ], PACKET_SIZE ) != 0 ;
599+ }
600+ }
601+
602+ /* Try the other way, now. Encrypt with wolfEngine, decrypt with wolfSSL. */
603+ if (err == 0 ) {
604+ err = EVP_CipherInit_ex (encCtx , EVP_aes_128_ctr (), e , key ,
605+ NULL , -1 ) != 1 ;
606+ }
607+ if (err == 0 ) {
608+ err = EVP_CipherInit_ex (decCtx , EVP_aes_128_ctr (), NULL , key ,
609+ NULL , -1 ) != 1 ;
610+ }
611+
612+ for (i = 0 ; err == 0 && i < NUM_PACKETS ; ++ i ) {
613+ if (err == 0 ) {
614+ err = EVP_CipherInit_ex (encCtx , NULL , e , NULL , ivs [i ], 1 ) != 1 ;
615+ }
616+ if (err == 0 ) {
617+ err = EVP_CipherInit_ex (decCtx , NULL , NULL , NULL , ivs [i ], 0 ) != 1 ;
618+ }
619+ if (err == 0 ) {
620+ err = EVP_Cipher (encCtx , encText , packets [i ], PACKET_SIZE ) < 0 ;
621+ }
622+ if (err == 0 ) {
623+ err = EVP_Cipher (decCtx , decText , encText , PACKET_SIZE ) < 0 ;
624+ }
625+ if (err == 0 ) {
626+ err = memcmp (decText , packets [i ], PACKET_SIZE ) != 0 ;
627+ }
628+ }
629+
630+ if (encCtx != NULL )
631+ EVP_CIPHER_CTX_free (encCtx );
632+ if (decCtx != NULL )
633+ EVP_CIPHER_CTX_free (decCtx );
634+
635+ return err ;
636+ }
637+
638+ /*
639+ * OpenSSL allows the user to call EVP_CipherInit with NULL key or IV. In the
518640 * past, setting the IV first (with key NULL) with wolfEngine and then setting
519641 * the key (with IV NULL) would result in the IV getting set to 0s on the call
520642 * to set the key. This was discovered in testing with OpenSSH. This is a
521- * regression test to ensure we preserve the IV in this scenario. */
643+ * regression test to ensure we preserve the IV in this scenario.
644+ */
522645int test_aes_ctr_iv_init_regression (ENGINE * e , void * data )
523646{
524647 int err = 0 ;
0 commit comments