/**
  GCM multiply by H
  @param gcm   The GCM state which holds the H value
  @param I     The value to multiply H by
 */
void gcm_mult_h(gcm_state *gcm, unsigned char *I)
{
   unsigned char T[16];
#ifdef GCM_TABLES
   int x, y;
#ifdef GCM_TABLES_SSE2
   asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0]));
   for (x = 1; x < 16; x++) {
      asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0]));
   }
   asm("movdqa %%xmm0,(%0)"::"r"(&T));
#else
   XMEMCPY(T, &gcm->PC[0][I[0]][0], 16);
   for (x = 1; x < 16; x++) {
#ifdef LTC_FAST
       for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
           *((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][I[x]][y]));
       }
#else
       for (y = 0; y < 16; y++) {
           T[y] ^= gcm->PC[x][I[x]][y];
       }
#endif /* LTC_FAST */
   }
#endif /* GCM_TABLES_SSE2 */
#else     
   gcm_gf_mult(gcm->H, I, T); 
#endif
   XMEMCPY(I, T, 16);
}
예제 #2
0
파일: lrw_setiv.c 프로젝트: DINKIN/omim
/**
  Set the IV for LRW
  @param IV      The IV, must be 16 octets
  @param len     Length ... must be 16 :-)
  @param lrw     The LRW state to update
  @return CRYPT_OK if successful
*/
int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw)
{
   int           err;
#ifdef LTC_LRW_TABLES
   unsigned char T[16];
   int           x, y;
#endif
   LTC_ARGCHK(IV != NULL);
   LTC_ARGCHK(lrw != NULL);

   if (len != 16) {
      return CRYPT_INVALID_ARG;
   }

   if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) {
      return err;
   }

   /* copy the IV */
   XMEMCPY(lrw->IV, IV, 16);

   /* check if we have to actually do work */
   if (cipher_descriptor[lrw->cipher].accel_lrw_encrypt != NULL && cipher_descriptor[lrw->cipher].accel_lrw_decrypt != NULL) {
       /* we have accelerators, let's bail since they don't use lrw->pad anyways */
       return CRYPT_OK;
   }

#ifdef LTC_LRW_TABLES
   XMEMCPY(T, &lrw->PC[0][IV[0]][0], 16);
   for (x = 1; x < 16; x++) {
#ifdef LTC_FAST
       for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
           *((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&lrw->PC[x][IV[x]][y]));
       }
#else
       for (y = 0; y < 16; y++) {
           T[y] ^= lrw->PC[x][IV[x]][y];
       }
#endif
   }
   XMEMCPY(lrw->pad, T, 16);
#else
   gcm_gf_mult(lrw->tweak, IV, lrw->pad);
#endif

   return CRYPT_OK;
}
예제 #3
0
파일: lrw_process.c 프로젝트: DINKIN/omim
/**
  Process blocks with LRW, since decrypt/encrypt are largely the same they share this code.
  @param pt        The "input" data
  @param ct        [out] The "output" data
  @param len       The length of the input, must be a multiple of 128-bits (16 octets)
  @param mode      LRW_ENCRYPT or LRW_DECRYPT
  @param lrw       The LRW state
  @return  CRYPT_OK if successful
*/
int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw)
{
   unsigned char prod[16];
   int           x, err;
#ifdef LTC_LRW_TABLES
   int           y;
#endif

   LTC_ARGCHK(pt  != NULL);
   LTC_ARGCHK(ct  != NULL);
   LTC_ARGCHK(lrw != NULL);

   if (len & 15) {
      return CRYPT_INVALID_ARG;
   }

   while (len) {
      /* copy pad */
      XMEMCPY(prod, lrw->pad, 16);

      /* increment IV */
      for (x = 15; x >= 0; x--) {
          lrw->IV[x] = (lrw->IV[x] + 1) & 255;
          if (lrw->IV[x]) {
              break;
          }
      }

      /* update pad */
#ifdef LTC_LRW_TABLES
      /* for each byte changed we undo it's affect on the pad then add the new product */
      for (; x < 16; x++) {
#ifdef LTC_FAST
          for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
              *((LTC_FAST_TYPE *)(lrw->pad + y)) ^= *((LTC_FAST_TYPE *)(&lrw->PC[x][lrw->IV[x]][y])) ^ *((LTC_FAST_TYPE *)(&lrw->PC[x][(lrw->IV[x]-1)&255][y]));
          }
#else
          for (y = 0; y < 16; y++) {
              lrw->pad[y] ^= lrw->PC[x][lrw->IV[x]][y] ^ lrw->PC[x][(lrw->IV[x]-1)&255][y];
          }
#endif
      }
#else
      gcm_gf_mult(lrw->tweak, lrw->IV, lrw->pad);
#endif

      /* xor prod */
#ifdef LTC_FAST
      for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
           *((LTC_FAST_TYPE *)(ct + x)) = *((LTC_FAST_TYPE *)(pt + x)) ^ *((LTC_FAST_TYPE *)(prod + x));
      }
#else
      for (x = 0; x < 16; x++) {
         ct[x] = pt[x] ^ prod[x];
      }
#endif

      /* send through cipher */
      if (mode == LRW_ENCRYPT) {
         if ((err = cipher_descriptor[lrw->cipher].ecb_encrypt(ct, ct, &lrw->key)) != CRYPT_OK) {
            return err;
         }
      } else {
         if ((err = cipher_descriptor[lrw->cipher].ecb_decrypt(ct, ct, &lrw->key)) != CRYPT_OK) {
            return err;
         }
      }

      /* xor prod */
#ifdef LTC_FAST
      for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
           *((LTC_FAST_TYPE *)(ct + x)) = *((LTC_FAST_TYPE *)(ct + x)) ^ *((LTC_FAST_TYPE *)(prod + x));
      }
#else
      for (x = 0; x < 16; x++) {
         ct[x] = ct[x] ^ prod[x];
      }
#endif

      /* move to next */
      pt  += 16;
      ct  += 16;
      len -= 16;
   }

   return CRYPT_OK;
}
예제 #4
0
/**
  Initialize the LRW context
  @param cipher        The cipher desired, must be a 128-bit block cipher
  @param IV            The index value, must be 128-bits
  @param key           The cipher key
  @param keylen        The length of the cipher key in octets
  @param tweak         The tweak value (second key), must be 128-bits
  @param num_rounds    The number of rounds for the cipher (0 == default)
  @param lrw           [out] The LRW state
  @return CRYPT_OK on success.
*/
int lrw_start(               int   cipher,
              const unsigned char *IV,
              const unsigned char *key,       int keylen,
              const unsigned char *tweak,
                             int  num_rounds,
                   symmetric_LRW *lrw)
{
   int           err;
#ifdef LTC_LRW_TABLES
   unsigned char B[16];
   int           x, y, z, t;
#endif

   LTC_ARGCHK(IV    != NULL);
   LTC_ARGCHK(key   != NULL);
   LTC_ARGCHK(tweak != NULL);
   LTC_ARGCHK(lrw   != NULL);

#ifdef LTC_FAST
   if (16 % sizeof(LTC_FAST_TYPE)) {
      return CRYPT_INVALID_ARG;
   }
#endif

   /* is cipher valid? */
   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
      return err;
   }
   if (cipher_descriptor[cipher].block_length != 16) {
      return CRYPT_INVALID_CIPHER;
   }

   /* schedule key */
   if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &lrw->key)) != CRYPT_OK) {
      return err;
   }
   lrw->cipher = cipher;

   /* copy the IV and tweak */
   XMEMCPY(lrw->tweak, tweak, 16);

#ifdef LTC_LRW_TABLES
   /* setup tables */
   /* generate the first table as it has no shifting (from which we make the other tables) */
   zeromem(B, 16);
   for (y = 0; y < 256; y++) {
        B[0] = y;
        gcm_gf_mult(tweak, B, &lrw->PC[0][y][0]);
   }

   /* now generate the rest of the tables based the previous table */
   for (x = 1; x < 16; x++) {
      for (y = 0; y < 256; y++) {
         /* now shift it right by 8 bits */
         t = lrw->PC[x-1][y][15];
         for (z = 15; z > 0; z--) {
             lrw->PC[x][y][z] = lrw->PC[x-1][y][z-1];
         }
         lrw->PC[x][y][0]  = gcm_shift_table[t<<1];
         lrw->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1];
      }
   }
#endif

   /* generate first pad */
   return lrw_setiv(IV, 16, lrw);
}
예제 #5
0
/**
  Initialize a GCM state
  @param gcm     The GCM state to initialize
  @param cipher  The index of the cipher to use
  @param key     The secret key
  @param keylen  The length of the secret key
  @return CRYPT_OK on success
 */
int gcm_init(gcm_state *gcm, int cipher, 
             const unsigned char *key,  int keylen)
{
   int           err;
   unsigned char B[16];
#ifdef GCM_TABLES
   int           x, y, z, t;
#endif

   LTC_ARGCHK(gcm != NULL);
   LTC_ARGCHK(key != NULL);

#ifdef LTC_FAST
   if (16 % sizeof(LTC_FAST_TYPE)) {
      return CRYPT_INVALID_ARG;
   }
#endif

   /* is cipher valid? */
   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
      return err;
   }
   if (cipher_descriptor[cipher].block_length != 16) {
      return CRYPT_INVALID_CIPHER;
   }

   /* schedule key */
   if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) {
      return err;
   }

   /* H = E(0) */
   zeromem(B, 16);
   if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
      return err;
   }

   /* setup state */
   zeromem(gcm->buf, sizeof(gcm->buf));
   zeromem(gcm->X,   sizeof(gcm->X));
   gcm->cipher   = cipher;
   gcm->mode     = GCM_MODE_IV;
   gcm->ivmode   = 0;
   gcm->buflen   = 0;
   gcm->totlen   = 0;
   gcm->pttotlen = 0;

#ifdef GCM_TABLES
   /* setup tables */

   /* generate the first table as it has no shifting (from which we make the other tables) */
   zeromem(B, 16);
   for (y = 0; y < 256; y++) {
        B[0] = y;
        gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]);
   }

   /* now generate the rest of the tables based the previous table */
   for (x = 1; x < 16; x++) {
      for (y = 0; y < 256; y++) {
         /* now shift it right by 8 bits */
         t = gcm->PC[x-1][y][15];
         for (z = 15; z > 0; z--) {
             gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1];
         }
         gcm->PC[x][y][0] = gcm_shift_table[t<<1];
         gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1];
     }
  }

#endif

   return CRYPT_OK;
}