Exemple #1
0
/* ===================   ELmD((5,10),127,0) Verified Decryption Function =================== */
int crypto_aead_decrypt(
unsigned char *m,unsigned long long *mlen,
unsigned char *nsec,
const unsigned char *c, unsigned long long clen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k
)
{
	u8 param[]={0x5a,0,0x7f,0x80,0,0,0,0}; 
	
	block L, W, Delta_0, Delta_1, Delta_2, blk, result, CS;
	int i,j, flag = 0; u8 zeroes[16], ozs[16], blen = 16, Is_final = 0, Is_complete =1;
	unsigned long long outputmlen, blk_ctr=0, blk_ctr1=0;	
	for(i=0; i<16; i++)	{zeroes[i]=0x00;}   		// all zero.
	for(i=1; i<16; i++)	{ozs[i]=0x00;} ozs[0] = 0x80; 	//useful for padding.
	
	if(((clen % 16) != 1)||(clen < 33))
		return -1;
	// Bugfix from Nilanjan Datta, 22 Sep 2014
	if((c[clen-1]!= 0x00) && (c[clen-1]!=0x01))
        return -1;
	
	key_schedule(k);
	
	/* =========== Generate the Masks ========== */
	AES(10, ENCRYPT, L, zeroes, &aes_key1);

	mult_3(Delta_0, L); 
	mult_inv2(Delta_0, Delta_0); 

	mult_inv2(Delta_1, L); 

	mult_3(Delta_2, L); 
	mult_3(Delta_2, Delta_2); 
	mult_inv2(Delta_2, Delta_2);

	/* =============  Process Associated Data  ================ */
	for(i=0; i<16; i++)
		W[i]=0x00;
	process_AD(W, Delta_0, npub, param, ad, adlen); 

	
	 load_block(CS, zeroes, zeroes, 16, 0);

	 /* ================ Process Ciphertext Blocks ============ */
	 load_block(blk, c, zeroes, 16, 0);  

	 /* =================== Process 1st Block =================== */

	if( (clen==33) && (c[clen-1]==0x01) ) {
	 	process_block(Delta_2, Delta_1, result, blk, W, 0, DECRYPT, Is_final, CIPHERTEXT); 
		for(i=15; i>7; i--) { if(result[i]==0x80) { flag = 1; break; } }
		if(flag == 0) {return -1; }
		for(j=i+1; j<16; j++) { if(result[j]!=0) {return -1; }}
		store_bytes(m, result, 8, i-1); 
		outputmlen = i-8;
	 }
	 else {
		process_block(Delta_2, Delta_1, result, blk, W, 1, DECRYPT, Is_final, CIPHERTEXT);
		store_bytes(m, result, 8, 15);  m +=8; outputmlen = 8;
	 }
	 xor_block(CS, CS, result); store_bytes(nsec, result, 0, 7); 
	 clen -= 16; c+=16; blk_ctr ++; 

	/* ============= Process Successive Ciphertext Blocks ============== */

	while(clen > 17){
	   
	   load_block(blk, c, zeroes, 16, 0);  
	   if((clen == 33) && (c[clen-1]==0x01)) { 
	   	process_block(Delta_2, Delta_1, result, blk, W, 0, DECRYPT, Is_final, CIPHERTEXT); 
		i = -1;
		for(i=15; i>0; i--) { if(result[i]==0x80) { flag = 1; break; } }
		if(flag == 0) {return -1; }
		for(j=i+1; j<16; j++) { if(result[j]!=0) {return -1; }}
	   	store_bytes(m, result, 0, i-1); outputmlen += i;
	   }
	   else{ 
	        process_block(Delta_2, Delta_1, result, blk, W, 1, DECRYPT, Is_final, CIPHERTEXT); 
		store_bytes(m, result, 0, 15); outputmlen += 16;
	   } 

	   xor_block(CS, CS, result);
	   clen -= 16; c+=16; blk_ctr ++; 

	   if(clen != 17)
		   m +=16; 
	
	   if(blk_ctr == IT_GAP && blk_ctr1 < IT_MAX && clen > 48){ 
		AES(10, DECRYPT, result, W, &aes_key2); 
		mask(Delta_2, result, result, 1); 
		for(i=0; i<16; i++) { if(c[i] != result[i]) {return -1; } }
		c +=16; clen -= 16; blk_ctr =0; blk_ctr1++;
	   }
	   
	}

	/* ==========  Process checksum block  ============= */
	Is_final = 1;
	process_block(Delta_1, Delta_2, result, CS, W, 1, ENCRYPT, Is_final, MESSAGE); 
	for(i=0; i<16; i++) {if(result[i]!=c[i]) return -1;} 
	*mlen = outputmlen;
	
	return 0;
}
Exemple #2
0
/*
 * Algorithm independent CBC functions.
 */
int
cbc_encrypt_contiguous_blocks(cbc_ctx_t *ctx, char *data, size_t length,
    crypto_data_t *out, size_t block_size,
    int (*encrypt)(const void *, const uint8_t *, uint8_t *),
    void (*copy_block)(uint8_t *, uint8_t *),
    void (*xor_block)(uint8_t *, uint8_t *))
{
	size_t remainder = length;
	size_t need = 0;
	uint8_t *datap = (uint8_t *)data;
	uint8_t *blockp;
	uint8_t *lastp;
	void *iov_or_mp;
	offset_t offset;
	uint8_t *out_data_1;
	uint8_t *out_data_2;
	size_t out_data_1_len;

	if (length + ctx->cbc_remainder_len < block_size) {
		/* accumulate bytes here and return */
		bcopy(datap,
		    (uint8_t *)ctx->cbc_remainder + ctx->cbc_remainder_len,
		    length);
		ctx->cbc_remainder_len += length;
		ctx->cbc_copy_to = datap;
		return (CRYPTO_SUCCESS);
	}

	lastp = (uint8_t *)ctx->cbc_iv;
	if (out != NULL)
		crypto_init_ptrs(out, &iov_or_mp, &offset);

	do {
		/* Unprocessed data from last call. */
		if (ctx->cbc_remainder_len > 0) {
			need = block_size - ctx->cbc_remainder_len;

			if (need > remainder)
				return (CRYPTO_DATA_LEN_RANGE);

			bcopy(datap, &((uint8_t *)ctx->cbc_remainder)
			    [ctx->cbc_remainder_len], need);

			blockp = (uint8_t *)ctx->cbc_remainder;
		} else {
			blockp = datap;
		}

		if (out == NULL) {
			/*
			 * XOR the previous cipher block or IV with the
			 * current clear block.
			 */
			xor_block(lastp, blockp);
			encrypt(ctx->cbc_keysched, blockp, blockp);

			ctx->cbc_lastp = blockp;
			lastp = blockp;

			if (ctx->cbc_remainder_len > 0) {
				bcopy(blockp, ctx->cbc_copy_to,
				    ctx->cbc_remainder_len);
				bcopy(blockp + ctx->cbc_remainder_len, datap,
				    need);
			}
		} else {
			/*
			 * XOR the previous cipher block or IV with the
			 * current clear block.
			 */
			xor_block(blockp, lastp);
			encrypt(ctx->cbc_keysched, lastp, lastp);
			crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
			    &out_data_1_len, &out_data_2, block_size);

			/* copy block to where it belongs */
			if (out_data_1_len == block_size) {
				copy_block(lastp, out_data_1);
			} else {
				bcopy(lastp, out_data_1, out_data_1_len);
				if (out_data_2 != NULL) {
					bcopy(lastp + out_data_1_len,
					    out_data_2,
					    block_size - out_data_1_len);
				}
			}
			/* update offset */
			out->cd_offset += block_size;
		}

		/* Update pointer to next block of data to be processed. */
		if (ctx->cbc_remainder_len != 0) {
			datap += need;
			ctx->cbc_remainder_len = 0;
		} else {
			datap += block_size;
		}

		remainder = (size_t)&data[length] - (size_t)datap;

		/* Incomplete last block. */
		if (remainder > 0 && remainder < block_size) {
			bcopy(datap, ctx->cbc_remainder, remainder);
			ctx->cbc_remainder_len = remainder;
			ctx->cbc_copy_to = datap;
			goto out;
		}
		ctx->cbc_copy_to = NULL;

	} while (remainder > 0);

out:
	/*
	 * Save the last encrypted block in the context.
	 */
	if (ctx->cbc_lastp != NULL) {
		copy_block((uint8_t *)ctx->cbc_lastp, (uint8_t *)ctx->cbc_iv);
		ctx->cbc_lastp = (uint8_t *)ctx->cbc_iv;
	}

	return (CRYPTO_SUCCESS);
}
// If encr, encrypts, otherwise decrypts
// Lua arguments:
// string text (may be cleartext or encrypted text)
// string password
// sha256(password) is used as key for twofish
// returns cleartext or encrypted text
static int twofish_twoways(lua_State *L, int encr) {
    if (lua_gettop(L) != 2) {
        return 0;
    }
    if (lua_type(L, 1) != LUA_TSTRING) {
        return 0;
    }
    if (lua_type(L, 2) != LUA_TSTRING) {
        return 0;
    }
    size_t text_s;
    const char* text = lua_tolstring(L, 1, &text_s);
    size_t password_s;
    const char* password = lua_tolstring(L, 2, &password_s);
    // sha256
    unsigned char sha256sum[32];
    calc_sha256(sha256sum, password, password_s);
    // twofish - prepare key
    u32 *S;
    u32 K[40];
    int k;
    keySched(sha256sum, 256, &S, K, &k);
    u32 QF[4][256];
    fullKey(S, k, QF);
    free(S);
    // allocate output string
    // nonce is stored in the beginning
    int result_bytes;
    if (encr) {
        result_bytes = text_s + BLOCK_BYTES;
    } else {
        result_bytes = text_s - BLOCK_BYTES;
    }
    if (result_bytes <= 0) {
        return 0;
    }
    char* result = malloc(result_bytes);
    // twofish - make nonce (~IV) for CTR mode
    const char* nonce;
    const char* input; // points to first block of data
    char* output; // points to first block of data
    int normal_blocks;
    if (encr) {
        char* nonce_mut = result;
        nonce = nonce_mut;
        get_random_bytes(nonce_mut, BLOCK_BYTES);
        input = text;
        output = result + BLOCK_BYTES;
        normal_blocks = text_s / BLOCK_BYTES;
    } else {
        nonce = text;
        input = text + BLOCK_BYTES;
        output = result;
        normal_blocks = (text_s / BLOCK_BYTES) - 1;
    }
    int i;
    for (i = 0; i < normal_blocks; i++) {
        const char* b_in = input + i * BLOCK_BYTES;
        char* b_out = output + i * BLOCK_BYTES;
        memcpy(b_out, nonce, BLOCK_BYTES);
        xor_ctr(b_out, i);
        encrypt(K, QF, b_out);
        xor_block(b_out, b_in, BLOCK_BYTES);
    }
    int last_block_size = text_s % BLOCK_BYTES;
    if (last_block_size) {
        const char* b_in = input + normal_blocks * BLOCK_BYTES;
        char* b_out = output + normal_blocks * BLOCK_BYTES;
        char block[BLOCK_BYTES];
        memcpy(block, nonce, BLOCK_BYTES);
        xor_ctr(block, normal_blocks);
        encrypt(K, QF, block);
        memcpy(b_out, block, last_block_size);
        xor_block(b_out, b_in, last_block_size);
    }
    lua_pushlstring(L, result, result_bytes);
    free(result);
    return 1;
}
Exemple #4
0
static void add_round_key( uint_8t d[N_BLOCK], const uint_8t k[N_BLOCK] )
{
    xor_block(d, k);
}
Exemple #5
0
/*
 * Encrypt and decrypt multiple blocks of data in counter mode.
 */
int
ctr_mode_contiguous_blocks(ctr_ctx_t *ctx, char *data, size_t length,
    crypto_data_t *out, size_t block_size,
    int (*cipher)(const void *ks, const uint8_t *pt, uint8_t *ct),
    void (*xor_block)(uint8_t *, uint8_t *))
{
	size_t remainder = length;
	size_t need = 0;
	uint8_t *datap = (uint8_t *)data;
	uint8_t *blockp;
	uint8_t *lastp;
	void *iov_or_mp;
	offset_t offset;
	uint8_t *out_data_1;
	uint8_t *out_data_2;
	size_t out_data_1_len;
	uint64_t lower_counter, upper_counter;

	if (length + ctx->ctr_remainder_len < block_size) {
		/* accumulate bytes here and return */
		bcopy(datap,
		    (uint8_t *)ctx->ctr_remainder + ctx->ctr_remainder_len,
		    length);
		ctx->ctr_remainder_len += length;
		ctx->ctr_copy_to = datap;
		return (CRYPTO_SUCCESS);
	}

	lastp = (uint8_t *)ctx->ctr_cb;
	if (out != NULL)
		crypto_init_ptrs(out, &iov_or_mp, &offset);

	do {
		/* Unprocessed data from last call. */
		if (ctx->ctr_remainder_len > 0) {
			need = block_size - ctx->ctr_remainder_len;

			if (need > remainder)
				return (CRYPTO_DATA_LEN_RANGE);

			bcopy(datap, &((uint8_t *)ctx->ctr_remainder)
			    [ctx->ctr_remainder_len], need);

			blockp = (uint8_t *)ctx->ctr_remainder;
		} else {
			blockp = datap;
		}

		/* ctr_cb is the counter block */
		cipher(ctx->ctr_keysched, (uint8_t *)ctx->ctr_cb,
		    (uint8_t *)ctx->ctr_tmp);

		lastp = (uint8_t *)ctx->ctr_tmp;

		/*
		 * Increment Counter.
		 */
		lower_counter = ntohll(ctx->ctr_cb[1] & ctx->ctr_lower_mask);
		lower_counter = htonll(lower_counter + 1);
		lower_counter &= ctx->ctr_lower_mask;
		ctx->ctr_cb[1] = (ctx->ctr_cb[1] & ~(ctx->ctr_lower_mask)) |
		    lower_counter;

		/* wrap around */
		if (lower_counter == 0) {
			upper_counter =
			    ntohll(ctx->ctr_cb[0] & ctx->ctr_upper_mask);
			upper_counter = htonll(upper_counter + 1);
			upper_counter &= ctx->ctr_upper_mask;
			ctx->ctr_cb[0] =
			    (ctx->ctr_cb[0] & ~(ctx->ctr_upper_mask)) |
			    upper_counter;
		}

		/*
		 * XOR encrypted counter block with the current clear block.
		 */
		xor_block(blockp, lastp);

		if (out == NULL) {
			if (ctx->ctr_remainder_len > 0) {
				bcopy(lastp, ctx->ctr_copy_to,
				    ctx->ctr_remainder_len);
				bcopy(lastp + ctx->ctr_remainder_len, datap,
				    need);
			}
		} else {
			crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1,
			    &out_data_1_len, &out_data_2, block_size);

			/* copy block to where it belongs */
			bcopy(lastp, out_data_1, out_data_1_len);
			if (out_data_2 != NULL) {
				bcopy(lastp + out_data_1_len, out_data_2,
				    block_size - out_data_1_len);
			}
			/* update offset */
			out->cd_offset += block_size;
		}

		/* Update pointer to next block of data to be processed. */
		if (ctx->ctr_remainder_len != 0) {
			datap += need;
			ctx->ctr_remainder_len = 0;
		} else {
			datap += block_size;
		}

		remainder = (size_t)&data[length] - (size_t)datap;

		/* Incomplete last block. */
		if (remainder > 0 && remainder < block_size) {
			bcopy(datap, ctx->ctr_remainder, remainder);
			ctx->ctr_remainder_len = remainder;
			ctx->ctr_copy_to = datap;
			goto out;
		}
		ctx->ctr_copy_to = NULL;

	} while (remainder > 0);

out:
	return (CRYPTO_SUCCESS);
}
int decrypt_final(struct poet_ctx *ctx, const uint8_t *ciphertext,
           uint64_t clen, const uint8_t tag[BLOCKLEN],
           uint8_t *plaintext)
{
#ifdef DEBUG
  int i;
#endif
  uint64_t offset=0;
  block s;
  block tmp;
  block tmp2;
  int alpha;
  int beta;
  uint64_t len;

  while( clen > BLOCKLEN )
    {
      decrypt_block(ctx, ciphertext+offset, plaintext+offset);
      clen   -= BLOCKLEN;
      offset += BLOCKLEN;
    }

  /* Encrypt length of message */
  ctx->mlen+=(clen*8);
  memset(s,0,BLOCKLEN);
  len =  TO_LITTLE_ENDIAN_64(ctx->mlen);
  memcpy(s, &len, 8);
  AES_encrypt(s, s ,&(ctx->aes_enc));


  /* Last ciphertext block must be padded if necesscary */
  memcpy(tmp,ciphertext+offset,clen);
  memcpy(tmp+clen,tag,BLOCKLEN-clen);


  /* Process last block + tag generation */
  BOTTOM_HASH;
  xor_block(tmp,s,tmp);
  xor_block(ctx->y, tmp,ctx->y);

  AES_decrypt(ctx->y, tmp, &(ctx->aes_dec));

  TOP_HASH;
  xor_block(tmp2, tmp, ctx->x);
  xor_block(tmp2, s, tmp2);
  memcpy(ctx->x,tmp,BLOCKLEN);


#ifdef DEBUG
  puts("S"); for(i=0;i<16;i++) printf("%02x ",s[i]); puts("");
  puts("X"); for(i=0;i<16;i++) printf("%02x ",ctx->x[i]); puts("");
  puts("Y"); for(i=0;i<16;i++) printf("%02x ",ctx->y[i]); puts("");
#endif

  /* Do tag splitting if needed */
  memcpy(plaintext+offset,tmp2,clen);

  alpha = memcmp(tmp2+clen,ctx->tau,BLOCKLEN-clen);

  /* Generate tag */
  TOP_HASH;
  xor_block(ctx->x, ctx->tau ,ctx->x);
  xor_block(ctx->x, ctx->tm ,ctx->x);

  AES_encrypt(ctx->x, tmp, &(ctx->aes_enc));

  BOTTOM_HASH;
  xor_block(tmp, ctx->y, tmp);
  xor_block(tmp, ctx->tm, tmp);

#ifdef DEBUG
  puts("tmp"); for(i=0;i<16;i++) printf("%02x ",tmp[i]); puts("");
  puts("tag"); for(i=0;i<16;i++) printf("%02x ",tag[i]); puts("");
#endif

  beta = memcmp(tmp,tag+(BLOCKLEN-clen),clen);

  return alpha|beta;
}
void encrypt_final(struct poet_ctx *ctx, const uint8_t *plaintext,
           uint64_t plen, uint8_t *ciphertext, uint8_t tag[BLOCKLEN])
{
#ifdef DEBUG
  int i;
#endif
  uint64_t offset=0;
  uint64_t len;
  block s;
  block tmp;
  block tmp2;
  while( plen > BLOCKLEN )
    {
      encrypt_block(ctx,  (plaintext+offset), (ciphertext+offset));
      plen   -= BLOCKLEN;
      offset += BLOCKLEN;
    }

  /* Encrypt length of message */
  ctx->mlen+=(plen*8);
  memset(s,0,BLOCKLEN);
  len =  TO_LITTLE_ENDIAN_64(ctx->mlen);
  memcpy(s, &len,8);
  AES_encrypt(s, s ,&(ctx->aes_enc));

  /* Last message block must be padded if necesscary */
  memcpy(tmp,plaintext+offset,plen);
  memcpy(tmp+plen,ctx->tau,BLOCKLEN-plen);


  /* Process last block + tag generation */

  TOP_HASH;
  xor_block(tmp,s,tmp);
  xor_block(ctx->x,tmp,ctx->x);

  AES_encrypt(ctx->x, tmp, &(ctx->aes_enc));

  BOTTOM_HASH;
  xor_block(tmp2, tmp,ctx->y);
  memcpy(ctx->y, tmp, BLOCKLEN);
  xor_block(tmp,s,tmp2);


#ifdef DEBUG
  puts("S"); for(i=0;i<16;i++) printf("%02x ",s[i]); puts("");
  puts("X"); for(i=0;i<16;i++) printf("%02x ",ctx->x[i]); puts("");
  puts("Y"); for(i=0;i<16;i++) printf("%02x ",ctx->y[i]); puts("");
#endif

  /* Do tag splitting if needed */
  memcpy(ciphertext+offset,tmp,plen);
  memcpy(tag,tmp+plen,BLOCKLEN-plen);


  /* Generate tag */
  TOP_HASH;
  xor_block(ctx->x, ctx->tau, ctx->x);
  xor_block(ctx->x, ctx->tm, ctx->x);

  AES_encrypt(ctx->x, tmp, &(ctx->aes_enc));

  BOTTOM_HASH;
  xor_block(tmp, ctx->y, tmp);
  xor_block(tmp, ctx->tm, tmp);

  memcpy(tag+(BLOCKLEN-plen),tmp,plen);

}
int
ccmp_encrypt(struct ieee80211_key *key, wbuf_t wbuf0, int hdrlen, int mfp)
{
    struct ccmp_ctx *ctx = key->wk_private;
    struct ieee80211_frame *wh;
    wbuf_t wbuf = wbuf0;
    int data_len, i, space;
    uint8_t aad[2 * AES_BLOCK_LEN], b0[AES_BLOCK_LEN], b[AES_BLOCK_LEN],
        e[AES_BLOCK_LEN], s0[AES_BLOCK_LEN];
    uint8_t *pos;

    ctx->cc_vap->iv_stats.is_crypto_ccmp++;
    wh = (struct ieee80211_frame *)wbuf_header(wbuf);
    data_len = wbuf_get_pktlen(wbuf) - (hdrlen + ccmp.ic_header);
    ccmp_init_blocks(&ctx->cc_aes, wh, key->wk_keytsc,
                     data_len, b0, aad, b, s0, mfp);

    i = 1;
    pos = (u_int8_t *)wbuf_header(wbuf) + hdrlen + ccmp.ic_header;
    /* NB: assumes header is entirely in first mbuf */
    space = wbuf_get_pktlen(wbuf) - (hdrlen + ccmp.ic_header);
    for (;;) {
        if (space > data_len)
            space = data_len;
        /*
         * Do full blocks.
         */
        while (space >= AES_BLOCK_LEN) {
            CCMP_ENCRYPT(i, b, b0, pos, e, AES_BLOCK_LEN);
            pos += AES_BLOCK_LEN, space -= AES_BLOCK_LEN;
            data_len -= AES_BLOCK_LEN;
            i++;
        }
        if (data_len <= 0)		/* no more data */
            break;
        wbuf = wbuf_next(wbuf);
        if (wbuf == NULL) {		/* last buffer */
            if (space != 0) {
                /*
                 * Short last block.
                 */
                CCMP_ENCRYPT(i, b, b0, pos, e, space);
            }
            break;
        }
#if 1 /* assume only one chunk */
        break;
#else
        if (space != 0) {
            uint8_t *pos_next;
            int space_next;
            int len, dl, sp;
            wbuf_t wbufi_new;

            /*
             * Block straddles one or more mbufs, gather data
             * into the block buffer b, apply the cipher, then
             * scatter the results back into the mbuf chain.
             * The buffer will automatically get space bytes
             * of data at offset 0 copied in+out by the
             * CCMP_ENCRYPT request so we must take care of
             * the remaining data.
             */
            wbuf_new = wbuf;
            dl = data_len;
            sp = space;
            for (;;) {
                pos_next = (u_int8_t *)wbuf_header(wbuf_new);
                len = min(dl, AES_BLOCK_LEN);
                space_next = len > sp ? len - sp : 0;
                if (wbuf_get_len(wbuf_new) >= space_next) {
                    /*
                     * This mbuf has enough data; just grab
                     * what we need and stop.
                     */
                    xor_block(b+sp, pos_next, space_next);
                    break;
                }
                /*
                 * This mbuf's contents are insufficient,
                 * take 'em all and prepare to advance to
                 * the next mbuf.
                 */
                xor_block(b+sp, pos_next, n->m_len);
                sp += wbuf_get_len(wbuf_new), dl -= wbuf_get_len(wbuf_new);
                wbuf_next = m_next;
                if (n == NULL)
                    break;
            }

            CCMP_ENCRYPT(i, b, b0, pos, e, space);

            /* NB: just like above, but scatter data to mbufs */
            dl = data_len;
            sp = space;
            for (;;) {
                pos_next = mtod(m, uint8_t *);
                len = min(dl, AES_BLOCK_LEN);
                space_next = len > sp ? len - sp : 0;
                if (m->m_len >= space_next) {
                    xor_block(pos_next, e+sp, space_next);
                    break;
                }
                xor_block(pos_next, e+sp, m->m_len);
                sp += m->m_len, dl -= m->m_len;
                m = m->m_next;
                if (m == NULL)
                    goto done;
            }
            /*
             * Do bookkeeping.  m now points to the last mbuf
             * we grabbed data from.  We know we consumed a
             * full block of data as otherwise we'd have hit
             * the end of the mbuf chain, so deduct from data_len.
             * Otherwise advance the block number (i) and setup
             * pos+space to reflect contents of the new mbuf.
             */
            data_len -= AES_BLOCK_LEN;
            i++;
            pos = pos_next + space_next;
            space = m->m_len - space_next;
        } else {
Exemple #9
0
int crypto_aead_encrypt(
unsigned char *c,unsigned long long *clen,
const unsigned char *m,unsigned long long mlen,
const unsigned char *ad,unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k
)
{
	u8 param[]={0x0a,0,0x7f,0x80,0x80,0,0,0}; 
	
	block L, W, Delta_0, Delta_1, Delta_2, blk, result, CS;
	int i; 
	unsigned long long h, cnt, blk_ctr=0, blk_ctr1=0 ;
	u8 zeroes[16], ozs[16], blen = 16, Is_final = 0, Is_complete =1;
	for(i=0; i<16; i++)	{zeroes[i]=0x00;}   	
	for(i=1; i<16; i++)	{ozs[i]=0x00;} ozs[0] = 0x80; 	

	cnt = (8+mlen-1)/16 + 1;
	h = (mlen+8-1) / (IT_GAP * 16);
	if(h > IT_MAX)
		h = IT_MAX;
	*clen = (cnt +1)* 16 + 1 + h*16 ;  

	if((mlen+8)%16 == 0) 
		c[*clen-1] = 0x00; 
	else 
		c[*clen-1] = 0x01; 

	key_schedule(k);

	/* ==========  Generate the Masks =========== */
	AES(10, ENCRYPT, L, zeroes, &aes_key1);
	//AES(6, ENCRYPT, blk, zeroes, &aes_key1);
	//AES(6, ENCRYPT, L, blk, &aes_key1);

	mult_3(Delta_0, L); 
	mult_inv2(Delta_0, Delta_0); 

	mult_inv2(Delta_1, L); 	

	mult_3(Delta_2, L); 
	mult_3(Delta_2, Delta_2); 
	mult_inv2(Delta_2, Delta_2);

	/* ======  Process Associated Data ======== */
	for(i=0; i<16; i++)
		W[i]=0x00;
	process_AD(W, Delta_0, npub, param, ad, adlen);


	/* ================  Process Message Blocks ==================== */

	
	/* ====== Process the first Message block, whose first 8 byte is the secret message number ===== */
	
	if(mlen < 8){ Is_complete = 0; }
	if(mlen <= 8) { blen = 8 + mlen; }
	load_block(blk, nsec, m, 8, blen-8); copy_block(CS, blk); 
	process_block(Delta_1, Delta_2, result, blk, W, Is_complete, ENCRYPT, Is_final, MESSAGE);
	
	store_bytes(c, result, 0, 15); c +=16; blk_ctr++; 
	if(mlen >= 8)  {mlen -= 8; m +=8;}
	else mlen = 0;

	/* ============= Process Successive Message blocks ================== */
	while(mlen > 0){
		if(mlen >= 16){
			load_block(blk, m, ozs, 16, 0); 
			if(mlen == 16) {xor_block(blk, blk, CS); }
			else xor_block(CS, CS, blk);
			blen = 16; mlen -= 16; m+=16; 
		}
		else 	{Is_complete = 0; blen = mlen; mlen = 0; 
			load_block(blk, m, ozs, blen, 0); xor_block(blk, CS, blk);
			
		}	
		process_block(Delta_1, Delta_2, result, blk, W, Is_complete, ENCRYPT, Is_final, MESSAGE); 
		store_bytes(c, result, 0, 15); c +=16; blk_ctr++; 
		
		if(blk_ctr == IT_GAP && blk_ctr1 < IT_MAX && mlen>0) {
			AES(10, DECRYPT, result, W, &aes_key2); 	
			mask(Delta_2, result, result, 1); 
			store_bytes(c, result, 0, 15); c +=16; blk_ctr =0; blk_ctr1++;
		}
	}

	/* ================ Process checksum block ====================== */
	process_block(Delta_1, Delta_2, result, blk, W, 1, ENCRYPT, 1, MESSAGE); 
	
	store_bytes(c, result, 0, 15);

	return 0;
}
Exemple #10
0
/* ===================   ELmD(6,127,1) Verified Decryption Function =================== */
int crypto_aead_decrypt(
unsigned char *m,unsigned long long *mlen,
unsigned char *nsec,
const unsigned char *c, unsigned long long clen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k
)
{
	u8 param[]={0x06,0,0x7f,0x81,0x80,0,0,0}; 
	
	block L, W, Delta_0, Delta_1, Delta_2, blk, result, CS;
	int i; u8 zeroes[16], ozs[16], blen = 16, Is_final = 0, Is_complete =1;
	unsigned long long outputmlen, blk_ctr=0, blk_ctr1=0;	
	for(i=0; i<16; i++)	{zeroes[i]=0x00;}   		// all zero.
	for(i=1; i<16; i++)	{ozs[i]=0x00;} ozs[0] = 0x80; 	//useful for padding.
	
	if(clen < 24)
		return -1;
	
	key_schedule(k);
	
	/* =========== Generate the Masks ========== */
	AES(6, ENCRYPT, blk, zeroes, &aes_key1);
	AES(6, ENCRYPT, L, blk, &aes_key1);

	mult_3(Delta_0, L); 
	mult_inv2(Delta_0, Delta_0); 

	mult_inv2(Delta_1, L); 

	mult_3(Delta_2, L); 
	mult_3(Delta_2, Delta_2); 
	mult_inv2(Delta_2, Delta_2);

	/* =============  Process Associated Data  ================ */
	for(i=0; i<16; i++)
		W[i]=0x00;
	process_AD(W, Delta_0, npub, param, ad, adlen); 

	
	 load_block(CS, zeroes, zeroes, 16, 0);

	 /* ================ Process Ciphertext Blocks ============ */
	 load_block(blk, c, zeroes, 16, 0);  

	 /* =================== Process 1st Block =================== */
	 if(clen<32){
	 	process_block(Delta_2, Delta_1, result, blk, W, 0, DECRYPT, Is_final, CIPHERTEXT); 
		store_bytes(m, result, 8, 8+(clen-25)); outputmlen = clen - 24;
	 }
	 else {
		process_block(Delta_2, Delta_1, result, blk, W, 1, DECRYPT, Is_final, CIPHERTEXT);
		store_bytes(m, result, 8, 15);  m +=8; outputmlen = 8;
	 }
	 xor_block(CS, CS, result); store_bytes(nsec, result, 0, 7); 
	 clen -= 16; c+=16; blk_ctr ++; 

	 if(clen < 16){ 
		if(result[clen] != 0x80) return -1; 
		for(i=clen+1; i<16; i++) {if(result[i]!=0) return -1;} 
	 }

	/* ============= Process Successive Ciphertext Blocks ============== */
	while(clen > 16){
	   
	   load_block(blk, c, zeroes, 16, 0);  
	   if(clen < 32){ 
	   	process_block(Delta_2, Delta_1, result, blk, W, 0, DECRYPT, Is_final, CIPHERTEXT); 
		xor_block(result, result, CS);
	   	store_bytes(m, result, 0, clen - 17); outputmlen += clen-16 ;
	   }
	   else{ 
	        process_block(Delta_2, Delta_1, result, blk, W, 1, DECRYPT, Is_final, CIPHERTEXT); 
		if(clen == 32) {xor_block(result, result, CS);}
		store_bytes(m, result, 0, 15); outputmlen += 16;
	   } 

	   xor_block(CS, CS, result);
	   clen -= 16; c+=16; blk_ctr ++; 

	   
	   if(clen < 16){ 
		if(result[clen] != 0x80) return -1; 
		for(i=clen+1; i<16; i++) {if(result[i]!=0) return -1;} 
	   }
	   else
		   m +=16; 

	   
	   if(blk_ctr == IT_GAP && blk_ctr1 < IT_MAX && clen > 32){ 
		AES(6, DECRYPT, result, W, &aes_key2); 
		mask(Delta_2, result, result, 1); 
		for(i=0; i<16; i++) { if(c[i] != result[i]) {return -1; } }
		c +=16; clen -= 16; blk_ctr =0; blk_ctr1++;
	   }
	   
	}

	/* ==========  Process checksum block  ============= */
	Is_final = 1;
	process_block(Delta_1, Delta_2, result, CS, W, 1, ENCRYPT, Is_final, MESSAGE); 
	for(i=0; i<clen; i++) {if(result[i]!=c[i]) return -1;} 
	*mlen = outputmlen;
	
	return 0;
}