@@ -341,12 +341,11 @@ public void testAesGcm128() throws WolfCryptException {
341341 plain = dec .decrypt (cipher , iv3 , tag , a3 );
342342 assertArrayEquals (p3 , plain );
343343
344- /* bad encrypt arguments: null input */
344+ /* encrypt with null input should pass */
345345 try {
346346 enc .encrypt (null , iv3 , tag , a3 );
347- fail ("encrypt() with null input should fail" );
348347 } catch (WolfCryptException e ) {
349- /* expected */
348+ fail ( "encrypt() with null input should pass" );
350349 }
351350
352351 /* bad encrypt arguments: null iv */
@@ -365,12 +364,11 @@ public void testAesGcm128() throws WolfCryptException {
365364 /* expected */
366365 }
367366
368- /* bad decrypt arguments: null input */
367+ /* decrypt with null input but valid tag and AAD should pass */
369368 try {
370369 enc .decrypt (null , iv3 , tag , a3 );
371- fail ("decrypt() with null input should fail" );
372370 } catch (WolfCryptException e ) {
373- /* expected */
371+ fail ( "decrypt() with null input should pass" );
374372 }
375373
376374 /* bad decrypt arguments: null iv */
@@ -422,12 +420,11 @@ public void testAesGcm192() throws WolfCryptException {
422420 assertNotNull (plain );
423421 assertArrayEquals (p , plain );
424422
425- /* bad encrypt arguments: null input */
423+ /* encrypt with null input should pass */
426424 try {
427425 enc .encrypt (null , iv2 , tag , a );
428- fail ("encrypt() with null input should fail" );
429426 } catch (WolfCryptException e ) {
430- /* expected */
427+ fail ( "encrypt() with null input should pass" );
431428 }
432429
433430 /* bad encrypt arguments: null iv */
@@ -446,12 +443,11 @@ public void testAesGcm192() throws WolfCryptException {
446443 /* expected */
447444 }
448445
449- /* bad decrypt arguments: null input */
446+ /* decrypt with null input but valid tag and AAD should pass */
450447 try {
451448 enc .decrypt (null , iv2 , tag , a );
452- fail ("decrypt() with null input should fail" );
453449 } catch (WolfCryptException e ) {
454- /* expected */
450+ fail ( "decrypt() with null input should pass" );
455451 }
456452
457453 /* bad decrypt arguments: null iv */
@@ -503,12 +499,11 @@ public void testAesGcm256() throws WolfCryptException {
503499 assertNotNull (plain );
504500 assertArrayEquals (p , plain );
505501
506- /* bad encrypt arguments: null input */
502+ /* encrypt with null input should pass */
507503 try {
508504 enc .encrypt (null , iv1 , tag , a );
509- fail ("encrypt() with null input should fail" );
510505 } catch (WolfCryptException e ) {
511- /* expected */
506+ fail ( "encrypt() with null input should pass" );
512507 }
513508
514509 /* bad encrypt arguments: null iv */
@@ -527,12 +522,11 @@ public void testAesGcm256() throws WolfCryptException {
527522 /* expected */
528523 }
529524
530- /* bad decrypt arguments: null input */
525+ /* decrypt with null input but valid tag and AAD should pass */
531526 try {
532527 enc .decrypt (null , iv1 , tag , a );
533- fail ("decrypt() with null input should fail" );
534528 } catch (WolfCryptException e ) {
535- /* expected */
529+ fail ( "decrypt() with null input should pass" );
536530 }
537531
538532 /* bad decrypt arguments: null iv */
@@ -1042,5 +1036,111 @@ public void testThreadedAes256() throws InterruptedException {
10421036 }
10431037 }
10441038 }
1039+
1040+ /**
1041+ * Test AES-GCM with null plaintext using test vectors from
1042+ * OpenJDK TestKATForGCM.java that have null plaintext input.
1043+ * This tests scenarios where users may only provide AAD to
1044+ * generate an authentication tag.
1045+ */
1046+ @ Test
1047+ public void testAesGcmWithNullPlaintext () throws WolfCryptException {
1048+
1049+ /*
1050+ * Test vector 1 from OpenJDK: AES-128, 96-bit IV,
1051+ * no plaintext, no AAD, 128-bit tag
1052+ */
1053+ byte [] key1 = new byte [] {
1054+ (byte )0x11 , (byte )0x75 , (byte )0x4c , (byte )0xd7 ,
1055+ (byte )0x2a , (byte )0xec , (byte )0x30 , (byte )0x9b ,
1056+ (byte )0xf5 , (byte )0x2f , (byte )0x76 , (byte )0x87 ,
1057+ (byte )0x21 , (byte )0x2e , (byte )0x89 , (byte )0x57
1058+ };
1059+ byte [] iv1 = new byte [] {
1060+ (byte )0x3c , (byte )0x81 , (byte )0x9d , (byte )0x9a ,
1061+ (byte )0x9b , (byte )0xed , (byte )0x08 , (byte )0x76 ,
1062+ (byte )0x15 , (byte )0x03 , (byte )0x0b , (byte )0x65
1063+ };
1064+ byte [] expectedTag1 = new byte [] {
1065+ (byte )0x25 , (byte )0x03 , (byte )0x27 , (byte )0xc6 ,
1066+ (byte )0x74 , (byte )0xaa , (byte )0xf4 , (byte )0x77 ,
1067+ (byte )0xae , (byte )0xf2 , (byte )0x67 , (byte )0x57 ,
1068+ (byte )0x48 , (byte )0xcf , (byte )0x69 , (byte )0x71
1069+ };
1070+
1071+ /*
1072+ * Test vector 6 from OpenJDK: AES-128, 96-bit IV,
1073+ * no plaintext, 16-byte AAD, 128-bit tag
1074+ */
1075+ byte [] key2 = new byte [] {
1076+ (byte )0x77 , (byte )0xbe , (byte )0x63 , (byte )0x70 ,
1077+ (byte )0x89 , (byte )0x71 , (byte )0xc4 , (byte )0xe2 ,
1078+ (byte )0x40 , (byte )0xd1 , (byte )0xcb , (byte )0x79 ,
1079+ (byte )0xe8 , (byte )0xd7 , (byte )0x7f , (byte )0xeb
1080+ };
1081+ byte [] iv2 = new byte [] {
1082+ (byte )0xe0 , (byte )0xe0 , (byte )0x0f , (byte )0x19 ,
1083+ (byte )0xfe , (byte )0xd7 , (byte )0xba , (byte )0x01 ,
1084+ (byte )0x36 , (byte )0xa7 , (byte )0x97 , (byte )0xf3
1085+ };
1086+ byte [] aad2 = new byte [] {
1087+ (byte )0x7a , (byte )0x43 , (byte )0xec , (byte )0x1d ,
1088+ (byte )0x9c , (byte )0x0a , (byte )0x5a , (byte )0x78 ,
1089+ (byte )0xa0 , (byte )0xb1 , (byte )0x65 , (byte )0x33 ,
1090+ (byte )0xa6 , (byte )0x21 , (byte )0x3c , (byte )0xab
1091+ };
1092+ byte [] expectedTag2 = new byte [] {
1093+ (byte )0x20 , (byte )0x9f , (byte )0xcc , (byte )0x8d ,
1094+ (byte )0x36 , (byte )0x75 , (byte )0xed , (byte )0x93 ,
1095+ (byte )0x8e , (byte )0x9c , (byte )0x71 , (byte )0x66 ,
1096+ (byte )0x70 , (byte )0x9d , (byte )0xd9 , (byte )0x46
1097+ };
1098+
1099+ /* skip test if AES-128 is not compiled in native library */
1100+ if (!FeatureDetect .Aes128Enabled ()) {
1101+ return ;
1102+ }
1103+
1104+ /* Test case 1: null plaintext, no AAD */
1105+ AesGcm enc = new AesGcm ();
1106+ enc .setKey (key1 );
1107+ byte [] tag = new byte [expectedTag1 .length ];
1108+ byte [] ciphertext = enc .encrypt (null , iv1 , tag , null );
1109+
1110+ /* Should return null/empty ciphertext since input was null */
1111+ assertTrue ("Ciphertext should be null or empty when input is null" ,
1112+ ciphertext == null || ciphertext .length == 0 );
1113+
1114+ /* Tag should match expected value */
1115+ assertArrayEquals ("Tag should match expected value for null " +
1116+ "plaintext, no AAD" , expectedTag1 , tag );
1117+ enc .releaseNativeStruct ();
1118+
1119+ /* Test case 2: null plaintext, with AAD */
1120+ enc = new AesGcm ();
1121+ enc .setKey (key2 );
1122+ tag = new byte [expectedTag2 .length ];
1123+ ciphertext = enc .encrypt (null , iv2 , tag , aad2 );
1124+
1125+ /* Should return null/empty ciphertext since input was null */
1126+ assertTrue ("Ciphertext should be null or empty when input is null" ,
1127+ ciphertext == null || ciphertext .length == 0 );
1128+
1129+ /* Tag should match expected value */
1130+ assertArrayEquals ("Tag should match expected value for null " +
1131+ "plaintext with AAD" , expectedTag2 , tag );
1132+
1133+ /* Test decryption with null ciphertext */
1134+ AesGcm dec = new AesGcm ();
1135+ dec .setKey (key2 );
1136+ byte [] plaintext = dec .decrypt (null , iv2 , tag , aad2 );
1137+
1138+ /* Should return null/empty plaintext since ciphertext was null */
1139+ assertTrue ("Plaintext should be null or empty when ciphertext " +
1140+ "is null" , plaintext == null || plaintext .length == 0 );
1141+
1142+ enc .releaseNativeStruct ();
1143+ dec .releaseNativeStruct ();
1144+ }
10451145}
10461146
0 commit comments