コード例 #1
0
ファイル: ocb3_done.c プロジェクト: FGasper/perl-CryptX
/**
   Finish OCB processing and compute the tag
   @param ocb     The OCB state
   @param tag     [out] The destination for the authentication tag
   @param taglen  [in/out] The max size and resulting size of the authentication tag
   @return CRYPT_OK if successful
*/
int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen)
{
   unsigned char tmp[MAXBLOCKSIZE];
   int err, x;

   LTC_ARGCHK(ocb    != NULL);
   LTC_ARGCHK(tag    != NULL);
   LTC_ARGCHK(taglen != NULL);
   if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
      goto LBL_ERR;
   }

   /* finalize AAD processing */

   if (ocb->adata_buffer_bytes>0) {
     /* Offset_* = Offset_m xor L_* */
     ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_star, ocb->block_len);

     /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
     ocb3_int_xor_blocks(tmp, ocb->adata_buffer, ocb->aOffset_current, ocb->adata_buffer_bytes);
     for(x=ocb->adata_buffer_bytes; x<ocb->block_len; x++) {
       if (x == ocb->adata_buffer_bytes) {
         tmp[x] = 0x80 ^ ocb->aOffset_current[x];
       }
       else {
         tmp[x] = 0x00 ^ ocb->aOffset_current[x];
       }
     }

     /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
     if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
       goto LBL_ERR;
     }
     ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
   }

   /* finalize TAG computing */

   /* at this point ocb->aSum_current = HASH(K, A) */
   /* tag = tag ^ HASH(K, A) */
   ocb3_int_xor_blocks(tmp, ocb->tag_part, ocb->aSum_current, ocb->block_len);

   /* fix taglen if needed */
   if ((int)*taglen > ocb->block_len) {
     *taglen = (unsigned long)ocb->block_len;
   }

   /* copy tag bytes */
   for(x=0; x<(int)*taglen; x++) tag[x] = tmp[x];

   err = CRYPT_OK;

LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(tmp, MAXBLOCKSIZE);
   zeromem(ocb, sizeof(*ocb));
#endif

   return err;
}
コード例 #2
0
ファイル: ocb3_encrypt.c プロジェクト: mrotteveel/firebird
/**
   Encrypt blocks of data with OCB
   @param ocb     The OCB state
   @param pt      The plaintext (length multiple of the block size of the block cipher)
   @param ptlen   The length of the input (octets)
   @param ct      [out] The ciphertext (same size as the pt)
   @return CRYPT_OK if successful
*/
int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)
{
   unsigned char tmp[MAXBLOCKSIZE];
   int err, i, full_blocks;
   unsigned char *pt_b, *ct_b;

   LTC_ARGCHK(ocb != NULL);
   if (ptlen == 0) return CRYPT_OK; /* no data, nothing to do */
   LTC_ARGCHK(pt != NULL);
   LTC_ARGCHK(ct != NULL);

   if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
      return err;
   }
   if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
      return CRYPT_INVALID_ARG;
   }

   if (ptlen % ocb->block_len) { /* ptlen has to bu multiple of block_len */
      return CRYPT_INVALID_ARG;
   }

   full_blocks = ptlen/ocb->block_len;
   for(i=0; i<full_blocks; i++) {
     pt_b = (unsigned char *)pt+i*ocb->block_len;
     ct_b = (unsigned char *)ct+i*ocb->block_len;

     /* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */
     ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len);

     /* tmp[] = pt[] XOR ocb->Offset_current[] */
     ocb3_int_xor_blocks(tmp, pt_b, ocb->Offset_current, ocb->block_len);

     /* encrypt */
     if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
        goto LBL_ERR;
     }

     /* ct[] = tmp[] XOR ocb->Offset_current[] */
     ocb3_int_xor_blocks(ct_b, tmp, ocb->Offset_current, ocb->block_len);

     /* ocb->checksum[] = ocb->checksum[] XOR pt[] */
     ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len);

     ocb->block_index++;
   }

   err = CRYPT_OK;

LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(tmp, sizeof(tmp));
#endif
   return err;
}
コード例 #3
0
ファイル: ocb3_add_aad.c プロジェクト: ybendan/libtomcrypt
/**
   Add one block of AAD data (internal function)
   @param ocb        The OCB state
   @param aad_block  [in] AAD data (block_len size)
   @return CRYPT_OK if successful
*/
static int _ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block)
{
   unsigned char tmp[MAXBLOCKSIZE];
   int err;

   /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
   ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_[ocb3_int_ntz(ocb->ablock_index)], ocb->block_len);

   /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
   ocb3_int_xor_blocks(tmp, aad_block, ocb->aOffset_current, ocb->block_len);
   if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
     return err;
   }
   ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);

   ocb->ablock_index++;

   return CRYPT_OK;
}
コード例 #4
0
/**
   Finish an OCB (decryption) stream
   @param ocb    The OCB state
   @param ct     The remaining ciphertext
   @param ctlen  The length of the ciphertext (octets)
   @param pt     [out] The output buffer
   @return CRYPT_OK if successful
*/
int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
{
   unsigned char iOffset_star[MAXBLOCKSIZE];
   unsigned char iPad[MAXBLOCKSIZE];
   int err, x, full_blocks, full_blocks_len, last_block_len;

   LTC_ARGCHK(ocb != NULL);
   LTC_ARGCHK(ct  != NULL);
   if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
      goto LBL_ERR;
   }

   full_blocks = ctlen/ocb->block_len;
   full_blocks_len = full_blocks * ocb->block_len;
   last_block_len = ctlen - full_blocks_len;

   /* process full blocks first */
   if (full_blocks>0) {
     if ((err = ocb3_decrypt(ocb, ct, full_blocks_len, pt)) != CRYPT_OK) {
       goto LBL_ERR;
     }
   }

   if (last_block_len>0) {
     /* Offset_* = Offset_m xor L_* */
     ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);

     /* Pad = ENCIPHER(K, Offset_*) */
     if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
       goto LBL_ERR;
     }

     /* P_* = C_* xor Pad[1..bitlen(C_*)] */
     ocb3_int_xor_blocks(pt+full_blocks_len, (unsigned char *)ct+full_blocks_len, iPad, last_block_len);

     /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
     ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
     for(x=last_block_len; x<ocb->block_len; x++) {
       if (x == last_block_len)
         ocb->checksum[x] ^= 0x80;
       else
         ocb->checksum[x] ^= 0x00;
     }

     /* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
     /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
     for(x=0; x<ocb->block_len; x++) {
       ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
     }
     if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
       goto LBL_ERR;
     }
   }
   else {
     /* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
     /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
     for(x=0; x<ocb->block_len; x++) {
       ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
     }
     if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
       goto LBL_ERR;
     }
   }

   err = CRYPT_OK;

LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(iOffset_star, MAXBLOCKSIZE);
   zeromem(iPad, MAXBLOCKSIZE);
#endif

   return err;
}