cryptosoft - (partially) fix AES_XTS for contiguous buffers
authorAlex Hornung <ahornung@gmail.com>
Sat, 21 Aug 2010 22:50:56 +0000 (23:50 +0100)
committerAlex Hornung <ahornung@gmail.com>
Sun, 22 Aug 2010 00:22:42 +0000 (01:22 +0100)
* The reinit magic skipping the iv mess for CBC was not being done for
  contiguous buffers, only for iovs and mbufs.

* This resulted in all test vectors for aes xts passing from userland
  (which uses iovs) but everything failing in kernel.

* Right now cryptsetup with -c aes-xts-plain still won't work, but at
  least some simple encryption and decryption tests work in kernel, too.

sys/opencrypto/cryptosoft.c

index 6b8f7c3..ea1f333 100644 (file)
@@ -117,13 +117,6 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
        ivp = iv;
 
        /*
-        * xforms that provide a reinit method perform all IV
-        * handling themselves.
-        */
-       if (exf->reinit)
-               exf->reinit(sw->sw_kschedule, iv);
-
-       /*
         * The semantics are seriously broken because the session key
         * storage was never designed for concurrent ops.
         */
@@ -142,6 +135,13 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
                explicit_kschedule = 0;
        }
 
+       /*
+        * xforms that provide a reinit method perform all IV
+        * handling themselves.
+        */
+       if (exf->reinit)
+               exf->reinit(kschedule, iv);
+
        if (flags & CRYPTO_F_IMBUF) {
                struct mbuf *m = (struct mbuf *) buf;
 
@@ -429,7 +429,16 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
                /*
                 * contiguous buffer
                 */
-               if (crd->crd_flags & CRD_F_ENCRYPT) {
+               if (exf->reinit) {
+                       for(i = crd->crd_skip;
+                           i < crd->crd_skip + crd->crd_len; i += blks) {
+                               if (crd->crd_flags & CRD_F_ENCRYPT) {
+                                       exf->encrypt(kschedule, buf + i);
+                               } else {
+                                       exf->decrypt(kschedule, buf + i);
+                               }
+                       }
+               } else if (crd->crd_flags & CRD_F_ENCRYPT) {
                        for (i = crd->crd_skip;
                            i < crd->crd_skip + crd->crd_len; i += blks) {
                                /* XOR with the IV/previous block, as appropriate. */