don't reveal plaintext if authentication failed
Create two buffers of the same size as the input data. Copy the input data to the first one and work with that version to hold the decrypted data, zeroize the second one. Copy depending on the verification result, either the zero-buffer or the real plaintext to the output buffer.
This commit is contained in:
		
							parent
							
								
									6c11ca771b
								
							
						
					
					
						commit
						09e4b0ec9b
					
				@ -48,7 +48,8 @@ int ccm_memory(int cipher,
 | 
				
			|||||||
          unsigned char *tag,    unsigned long *taglen,
 | 
					          unsigned char *tag,    unsigned long *taglen,
 | 
				
			||||||
                    int  direction)
 | 
					                    int  direction)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
   unsigned char  PAD[16], ctr[16], CTRPAD[16], ptTag[16], b;
 | 
					   unsigned char  PAD[16], ctr[16], CTRPAD[16], ptTag[16], b, *pt_real;
 | 
				
			||||||
 | 
					   unsigned char  *pt_work[2] = {0};
 | 
				
			||||||
   symmetric_key *skey;
 | 
					   symmetric_key *skey;
 | 
				
			||||||
   int            err;
 | 
					   int            err;
 | 
				
			||||||
   unsigned long  len, L, x, y, z, CTRlen;
 | 
					   unsigned long  len, L, x, y, z, CTRlen;
 | 
				
			||||||
@ -65,6 +66,8 @@ int ccm_memory(int cipher,
 | 
				
			|||||||
   LTC_ARGCHK(tag    != NULL);
 | 
					   LTC_ARGCHK(tag    != NULL);
 | 
				
			||||||
   LTC_ARGCHK(taglen != NULL);
 | 
					   LTC_ARGCHK(taglen != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   pt_real = pt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef LTC_FAST
 | 
					#ifdef LTC_FAST
 | 
				
			||||||
   if (16 % sizeof(LTC_FAST_TYPE)) {
 | 
					   if (16 % sizeof(LTC_FAST_TYPE)) {
 | 
				
			||||||
      return CRYPT_INVALID_ARG;
 | 
					      return CRYPT_INVALID_ARG;
 | 
				
			||||||
@ -140,6 +143,17 @@ int ccm_memory(int cipher,
 | 
				
			|||||||
   } else {
 | 
					   } else {
 | 
				
			||||||
      skey = uskey;
 | 
					      skey = uskey;
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 | 
					   if (direction != CCM_ENCRYPT) {
 | 
				
			||||||
 | 
					      pt_work[0] = XMALLOC(ptlen);
 | 
				
			||||||
 | 
					      pt_work[1] = XCALLOC(1, ptlen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if ((pt_work[0] == NULL) || (pt_work[1] == NULL)) {
 | 
				
			||||||
 | 
					         goto error;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      XMEMCPY(pt_work[0], pt, ptlen);
 | 
				
			||||||
 | 
					      pt = pt_work[0];
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /* form B_0 == flags | Nonce N | l(m) */
 | 
					   /* form B_0 == flags | Nonce N | l(m) */
 | 
				
			||||||
   x = 0;
 | 
					   x = 0;
 | 
				
			||||||
@ -346,13 +360,13 @@ int ccm_memory(int cipher,
 | 
				
			|||||||
       */
 | 
					       */
 | 
				
			||||||
      err = XMEM_NEQ(ptTag, PAD, *taglen);
 | 
					      err = XMEM_NEQ(ptTag, PAD, *taglen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /* TODO: pt should not be revealed when the tag is invalid. However, resetting the
 | 
					      /* Here err is 0 or 1, so we just copy either the real plaintext
 | 
				
			||||||
       *       memory should be done in constant time, which is not the case in the
 | 
					       * or the zeroized buffer.
 | 
				
			||||||
       *       (commented) code below.
 | 
					       */
 | 
				
			||||||
      if (err != CRYPT_OK) {
 | 
					      XMEMCPY(pt_real, pt_work[err], ptlen);
 | 
				
			||||||
         zeromem(pt, ptlen);
 | 
					#ifdef LTC_CLEAN_STACK
 | 
				
			||||||
      }
 | 
					      zeromem(pt_work[0], ptlen);
 | 
				
			||||||
      */
 | 
					#endif
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef LTC_CLEAN_STACK
 | 
					#ifdef LTC_CLEAN_STACK
 | 
				
			||||||
@ -361,6 +375,12 @@ int ccm_memory(int cipher,
 | 
				
			|||||||
   zeromem(CTRPAD, sizeof(CTRPAD));
 | 
					   zeromem(CTRPAD, sizeof(CTRPAD));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
error:
 | 
					error:
 | 
				
			||||||
 | 
					   if (pt_work[1]) {
 | 
				
			||||||
 | 
					      XFREE(pt_work[1]);
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   if (pt_work[0]) {
 | 
				
			||||||
 | 
					      XFREE(pt_work[0]);
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
   if (skey != uskey) {
 | 
					   if (skey != uskey) {
 | 
				
			||||||
      XFREE(skey);
 | 
					      XFREE(skey);
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user