SHA-512: Add AVX and AVX2 implementations for x86-64
[libgcrypt.git] / cipher / cipher-ofb.c
index e194976..3842774 100644 (file)
 
 gcry_err_code_t
 _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c,
-                          unsigned char *outbuf, unsigned int outbuflen,
-                          const unsigned char *inbuf, unsigned int inbuflen)
+                          unsigned char *outbuf, size_t outbuflen,
+                          const unsigned char *inbuf, size_t inbuflen)
 {
   unsigned char *ivp;
-  size_t blocksize = c->cipher->blocksize;
+  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+  size_t blocksize = c->spec->blocksize;
+  unsigned int burn, nburn;
 
   if (outbuflen < inbuflen)
     return GPG_ERR_BUFFER_TOO_SHORT;
@@ -46,12 +48,14 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c,
     {
       /* Short enough to be encoded by the remaining XOR mask. */
       /* XOR the input with the IV */
-      ivp = c->u_iv.iv + c->cipher->blocksize - c->unused;
+      ivp = c->u_iv.iv + blocksize - c->unused;
       buf_xor(outbuf, ivp, inbuf, inbuflen);
       c->unused -= inbuflen;
       return 0;
     }
 
+  burn = 0;
+
   if( c->unused )
     {
       inbuflen -= c->unused;
@@ -66,8 +70,8 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c,
   while ( inbuflen >= blocksize )
     {
       /* Encrypt the IV (and save the current one). */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      burn = nburn > burn ? nburn : burn;
       buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize);
       outbuf += blocksize;
       inbuf += blocksize;
@@ -75,8 +79,8 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c,
     }
   if ( inbuflen )
     { /* process the remaining bytes */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      burn = nburn > burn ? nburn : burn;
       c->unused = blocksize;
       c->unused -= inbuflen;
       buf_xor(outbuf, c->u_iv.iv, inbuf, inbuflen);
@@ -84,62 +88,9 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c,
       inbuf += inbuflen;
       inbuflen = 0;
     }
-  return 0;
-}
-
-
-gcry_err_code_t
-_gcry_cipher_ofb_decrypt (gcry_cipher_hd_t c,
-                          unsigned char *outbuf, unsigned int outbuflen,
-                          const unsigned char *inbuf, unsigned int inbuflen)
-{
-  unsigned char *ivp;
-  size_t blocksize = c->cipher->blocksize;
-
-  if (outbuflen < inbuflen)
-    return GPG_ERR_BUFFER_TOO_SHORT;
 
-  if( inbuflen <= c->unused )
-    {
-      /* Short enough to be encoded by the remaining XOR mask. */
-      ivp = c->u_iv.iv + blocksize - c->unused;
-      buf_xor(outbuf, ivp, inbuf, inbuflen);
-      c->unused -= inbuflen;
-      return 0;
-    }
-
-  if ( c->unused )
-    {
-      inbuflen -= c->unused;
-      ivp = c->u_iv.iv + blocksize - c->unused;
-      buf_xor(outbuf, ivp, inbuf, c->unused);
-      outbuf += c->unused;
-      inbuf += c->unused;
-      c->unused = 0;
-    }
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
 
-  /* Now we can process complete blocks. */
-  while ( inbuflen >= blocksize )
-    {
-      /* Encrypt the IV (and save the current one). */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize);
-      outbuf += blocksize;
-      inbuf += blocksize;
-      inbuflen -= blocksize;
-    }
-  if ( inbuflen )
-    { /* Process the remaining bytes. */
-      /* Encrypt the IV (and save the current one). */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      c->unused = blocksize;
-      c->unused -= inbuflen;
-      buf_xor(outbuf, c->u_iv.iv, inbuf, inbuflen);
-      outbuf += inbuflen;
-      inbuf += inbuflen;
-      inbuflen = 0;
-    }
   return 0;
 }