The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/crypto/chacha20/chacha.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2 chacha-merged.c version 20080118
    3 D. J. Bernstein
    4 Public domain.
    5 */
    6 
    7 /* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
    8 
    9 #include <sys/cdefs.h>
   10 __FBSDID("$FreeBSD$");
   11 
   12 #include <sys/param.h>
   13 #include <sys/types.h>
   14 
   15 #include <crypto/chacha20/chacha.h>
   16 
   17 typedef uint8_t u8;
   18 typedef uint32_t u32;
   19 
   20 typedef struct chacha_ctx chacha_ctx;
   21 
   22 #define U8C(v) (v##U)
   23 #define U32C(v) (v##U)
   24 
   25 #define U8V(v) ((u8)(v) & U8C(0xFF))
   26 #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
   27 
   28 #define ROTL32(v, n) \
   29   (U32V((v) << (n)) | ((v) >> (32 - (n))))
   30 
   31 #define U8TO32_LITTLE(p) \
   32   (((u32)((p)[0])      ) | \
   33    ((u32)((p)[1]) <<  8) | \
   34    ((u32)((p)[2]) << 16) | \
   35    ((u32)((p)[3]) << 24))
   36 
   37 #define U32TO8_LITTLE(p, v) \
   38   do { \
   39     (p)[0] = U8V((v)      ); \
   40     (p)[1] = U8V((v) >>  8); \
   41     (p)[2] = U8V((v) >> 16); \
   42     (p)[3] = U8V((v) >> 24); \
   43   } while (0)
   44 
   45 #define ROTATE(v,c) (ROTL32(v,c))
   46 #define XOR(v,w) ((v) ^ (w))
   47 #define PLUS(v,w) (U32V((v) + (w)))
   48 #define PLUSONE(v) (PLUS((v),1))
   49 
   50 #define QUARTERROUND(a,b,c,d) \
   51   a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
   52   c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
   53   a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
   54   c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
   55 
   56 static const char sigma[16] = "expand 32-byte k";
   57 static const char tau[16] = "expand 16-byte k";
   58 
   59 LOCAL void
   60 chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
   61 {
   62   const char *constants;
   63 
   64   x->input[4] = U8TO32_LITTLE(k + 0);
   65   x->input[5] = U8TO32_LITTLE(k + 4);
   66   x->input[6] = U8TO32_LITTLE(k + 8);
   67   x->input[7] = U8TO32_LITTLE(k + 12);
   68   if (kbits == 256) { /* recommended */
   69     k += 16;
   70     constants = sigma;
   71   } else { /* kbits == 128 */
   72     constants = tau;
   73   }
   74   x->input[8] = U8TO32_LITTLE(k + 0);
   75   x->input[9] = U8TO32_LITTLE(k + 4);
   76   x->input[10] = U8TO32_LITTLE(k + 8);
   77   x->input[11] = U8TO32_LITTLE(k + 12);
   78   x->input[0] = U8TO32_LITTLE(constants + 0);
   79   x->input[1] = U8TO32_LITTLE(constants + 4);
   80   x->input[2] = U8TO32_LITTLE(constants + 8);
   81   x->input[3] = U8TO32_LITTLE(constants + 12);
   82 }
   83 
   84 LOCAL void
   85 chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
   86 {
   87 #ifndef CHACHA_NONCE0_CTR128
   88   x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
   89   x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
   90   x->input[14] = U8TO32_LITTLE(iv + 0);
   91   x->input[15] = U8TO32_LITTLE(iv + 4);
   92 #else
   93   // CHACHA_STATELEN
   94   (void)iv;
   95   x->input[12] = U8TO32_LITTLE(counter + 0);
   96   x->input[13] = U8TO32_LITTLE(counter + 4);
   97   x->input[14] = U8TO32_LITTLE(counter + 8);
   98   x->input[15] = U8TO32_LITTLE(counter + 12);
   99 #endif
  100 }
  101 
  102 #ifdef CHACHA_NONCE0_CTR128
  103 LOCAL void
  104 chacha_ctrsave(const chacha_ctx *x, u8 *counter)
  105 {
  106     U32TO8_LITTLE(counter + 0, x->input[12]);
  107     U32TO8_LITTLE(counter + 4, x->input[13]);
  108     U32TO8_LITTLE(counter + 8, x->input[14]);
  109     U32TO8_LITTLE(counter + 12, x->input[15]);
  110 }
  111 #endif
  112 
  113 LOCAL void
  114 chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
  115 {
  116   u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
  117   u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
  118   u8 *ctarget = NULL;
  119   u8 tmp[64];
  120   u_int i;
  121 
  122   if (!bytes) return;
  123 
  124   j0 = x->input[0];
  125   j1 = x->input[1];
  126   j2 = x->input[2];
  127   j3 = x->input[3];
  128   j4 = x->input[4];
  129   j5 = x->input[5];
  130   j6 = x->input[6];
  131   j7 = x->input[7];
  132   j8 = x->input[8];
  133   j9 = x->input[9];
  134   j10 = x->input[10];
  135   j11 = x->input[11];
  136   j12 = x->input[12];
  137   j13 = x->input[13];
  138   j14 = x->input[14];
  139   j15 = x->input[15];
  140 
  141   for (;;) {
  142     if (bytes < 64) {
  143 #ifndef KEYSTREAM_ONLY
  144       for (i = 0;i < bytes;++i) tmp[i] = m[i];
  145       m = tmp;
  146 #endif
  147       ctarget = c;
  148       c = tmp;
  149     }
  150     x0 = j0;
  151     x1 = j1;
  152     x2 = j2;
  153     x3 = j3;
  154     x4 = j4;
  155     x5 = j5;
  156     x6 = j6;
  157     x7 = j7;
  158     x8 = j8;
  159     x9 = j9;
  160     x10 = j10;
  161     x11 = j11;
  162     x12 = j12;
  163     x13 = j13;
  164     x14 = j14;
  165     x15 = j15;
  166     for (i = 20;i > 0;i -= 2) {
  167       QUARTERROUND( x0, x4, x8,x12)
  168       QUARTERROUND( x1, x5, x9,x13)
  169       QUARTERROUND( x2, x6,x10,x14)
  170       QUARTERROUND( x3, x7,x11,x15)
  171       QUARTERROUND( x0, x5,x10,x15)
  172       QUARTERROUND( x1, x6,x11,x12)
  173       QUARTERROUND( x2, x7, x8,x13)
  174       QUARTERROUND( x3, x4, x9,x14)
  175     }
  176     x0 = PLUS(x0,j0);
  177     x1 = PLUS(x1,j1);
  178     x2 = PLUS(x2,j2);
  179     x3 = PLUS(x3,j3);
  180     x4 = PLUS(x4,j4);
  181     x5 = PLUS(x5,j5);
  182     x6 = PLUS(x6,j6);
  183     x7 = PLUS(x7,j7);
  184     x8 = PLUS(x8,j8);
  185     x9 = PLUS(x9,j9);
  186     x10 = PLUS(x10,j10);
  187     x11 = PLUS(x11,j11);
  188     x12 = PLUS(x12,j12);
  189     x13 = PLUS(x13,j13);
  190     x14 = PLUS(x14,j14);
  191     x15 = PLUS(x15,j15);
  192 
  193 #ifndef KEYSTREAM_ONLY
  194     x0 = XOR(x0,U8TO32_LITTLE(m + 0));
  195     x1 = XOR(x1,U8TO32_LITTLE(m + 4));
  196     x2 = XOR(x2,U8TO32_LITTLE(m + 8));
  197     x3 = XOR(x3,U8TO32_LITTLE(m + 12));
  198     x4 = XOR(x4,U8TO32_LITTLE(m + 16));
  199     x5 = XOR(x5,U8TO32_LITTLE(m + 20));
  200     x6 = XOR(x6,U8TO32_LITTLE(m + 24));
  201     x7 = XOR(x7,U8TO32_LITTLE(m + 28));
  202     x8 = XOR(x8,U8TO32_LITTLE(m + 32));
  203     x9 = XOR(x9,U8TO32_LITTLE(m + 36));
  204     x10 = XOR(x10,U8TO32_LITTLE(m + 40));
  205     x11 = XOR(x11,U8TO32_LITTLE(m + 44));
  206     x12 = XOR(x12,U8TO32_LITTLE(m + 48));
  207     x13 = XOR(x13,U8TO32_LITTLE(m + 52));
  208     x14 = XOR(x14,U8TO32_LITTLE(m + 56));
  209     x15 = XOR(x15,U8TO32_LITTLE(m + 60));
  210 #endif
  211 
  212     j12 = PLUSONE(j12);
  213     if (!j12) {
  214       j13 = PLUSONE(j13);
  215 #ifndef CHACHA_NONCE0_CTR128
  216       /* stopping at 2^70 bytes per nonce is user's responsibility */
  217 #else
  218       if (!j13) {
  219         j14 = PLUSONE(j14);
  220         if (!j14) {
  221           j15 = PLUSONE(j15);
  222         }
  223       }
  224 #endif
  225     }
  226 
  227     U32TO8_LITTLE(c + 0,x0);
  228     U32TO8_LITTLE(c + 4,x1);
  229     U32TO8_LITTLE(c + 8,x2);
  230     U32TO8_LITTLE(c + 12,x3);
  231     U32TO8_LITTLE(c + 16,x4);
  232     U32TO8_LITTLE(c + 20,x5);
  233     U32TO8_LITTLE(c + 24,x6);
  234     U32TO8_LITTLE(c + 28,x7);
  235     U32TO8_LITTLE(c + 32,x8);
  236     U32TO8_LITTLE(c + 36,x9);
  237     U32TO8_LITTLE(c + 40,x10);
  238     U32TO8_LITTLE(c + 44,x11);
  239     U32TO8_LITTLE(c + 48,x12);
  240     U32TO8_LITTLE(c + 52,x13);
  241     U32TO8_LITTLE(c + 56,x14);
  242     U32TO8_LITTLE(c + 60,x15);
  243 
  244     if (bytes <= 64) {
  245       if (bytes < 64) {
  246         for (i = 0;i < bytes;++i) ctarget[i] = c[i];
  247       }
  248       x->input[12] = j12;
  249       x->input[13] = j13;
  250 #ifdef CHACHA_NONCE0_CTR128
  251       x->input[14] = j14;
  252       x->input[15] = j15;
  253 #endif
  254       return;
  255     }
  256     bytes -= 64;
  257     c += 64;
  258 #ifndef KEYSTREAM_ONLY
  259     m += 64;
  260 #endif
  261   }
  262 }

Cache object: 6daeaaff3d26f54daa4134482e18582d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.