/* * plaintext, message length in byte, ciphertext, associated data, and associated data length in byte tag, and tag length in byte */ int ae_encrypt(ae_cxt* cxt, byte* pt, unsigned long long mlen, byte* ct, byte* tag, unsigned long long tlen, int enc_dec) { cxt->pt = pt; cxt->ptlen = mlen; cxt->ct = ct; cxt->ctlen = mlen; cxt->tag = tag; cxt->tlen = tlen; byte* es = cxt->es; byte* ts = cxt->ts; unsigned long long pc = 0; while((pc + STATE_LEN) < mlen){ if(enc_dec == ENC){ // encryption xor_bytes(es, pt+pc, STATE_LEN); memcpy(ct+pc, es, STATE_LEN); } else{ // decryption xor_bytes2(pt+pc, ct+pc, es, STATE_LEN); memcpy(es, ct+pc, STATE_LEN); } xor_bytes(ts, es, STATE_LEN); present_enc(ts, cxt->userkey); /* apply fix1 */ es[0] |= 0x80; present_enc(es, cxt->userkey); pc += STATE_LEN; } /* process the last block */ unsigned long long lastblocklen = mlen - pc; if(lastblocklen > 0){ if(enc_dec == ENC){ // encryption xor_bytes(es, pt+pc, lastblocklen); memcpy(ct+pc, es, lastblocklen); } else{ // decryption xor_bytes2(pt+pc, ct+pc, es, lastblocklen); memcpy(es, ct+pc, lastblocklen); } xor_bytes(ts, es, lastblocklen); present_enc(ts, cxt->userkey); } /* encode the adlen and process */ unsigned long long t_adlen = mlen; unsigned long long i; for(i = 0; i < sizeof(unsigned long long); i++) { ts[STATE_LEN-1-i] ^= t_adlen & 0xff; t_adlen >>= 8; } g(ts); present_enc(ts, cxt->userkey); memcpy(tag, ts, tlen); return SUCCESS; }
/* * plaintext, message length in byte, ciphertext, associated data, and associated data length in byte tag, and tag length in byte */ int ae_encrypt(ae_cxt* cxt, byte* pt, unsigned long long mlen, byte* ct, byte* tag, unsigned long long tlen, int enc_dec) { cxt->pt = pt; cxt->ptlen = mlen; cxt->ct = ct; cxt->ctlen = mlen; cxt->tag = tag; cxt->tlen = tlen; byte* es = cxt->es; byte* ts = cxt->ts; word* wd = (word*) ts; if(mlen != 0){ g2(wd[0], wd[1], wd[2], wd[3]); Encode(cxt->ts, cxt->ts); } else{ g1(wd[0], wd[1], wd[2], wd[3]); Encode(cxt->ts, cxt->ts); memcpy(tag, ts, tlen); return SUCCESS; } unsigned long long pc = 0; while((pc + STATE_LEN) < mlen){ if(enc_dec == ENC){ // encryption xor_bytes(es, pt+pc, STATE_LEN); pstate2("After xoring message block:", es); memcpy(ct+pc, es, STATE_LEN); } else{ // decryption xor_bytes2(pt+pc, ct+pc, es, STATE_LEN); pstate2("After xoring ciphertext block:", es); memcpy(es, ct+pc, STATE_LEN); } xor_bytes(ts, es, STATE_LEN); Encode(ts, ts); /* apply fix1 */ es[0] |= 0x80; pstate2("After applying fix1:", es); Encode(es, es); pc += STATE_LEN; } /* process the last block */ unsigned long long lastblocklen = mlen - pc; if(enc_dec == ENC){ // encryption xor_bytes(es, pt+pc, lastblocklen); pstate2("After xoring last partial message block:", es); memcpy(ct+pc, es, lastblocklen); } else{ // decryption xor_bytes2(pt+pc, ct+pc, es, lastblocklen); pstate2("After xoring last partial ciphertext block:", es); memcpy(es, ct+pc, lastblocklen); } xor_bytes(ts, es, lastblocklen); pstate2("tag state:", ts); if(lastblocklen != STATE_LEN){ // apply f2 /* apply padding only when last message block is not full */ ts[lastblocklen] ^= 0x80; word* wd = (word*) ts; f2(wd[0], wd[1], wd[2], wd[3]); } else{ // apply f1 word* wd = (word*) ts; f1(wd[0], wd[1], wd[2], wd[3]); } pstate2("After applying f1/f2:", ts); Encode(ts, ts); memcpy(tag, ts, tlen); return SUCCESS; }
void xor_bytes(byte*x, const byte*y, int nb) { xor_bytes2(x, x, y, nb); }
/* * plaintext, message length in byte, ciphertext, associated data, and associated data length in byte tag, and tag length in byte */ int ae_encrypt(ae_cxt* cxt, byte* pt, unsigned long long mlen, byte* ct, byte* tag, unsigned long long tlen, int enc_dec) { cxt->pt = pt; cxt->ptlen = mlen; cxt->ct = ct; cxt->ctlen = mlen; cxt->tag = tag; cxt->tlen = tlen; byte* es = cxt->es; byte* ts = cxt->ts; AES_KEY *ekey = cxt->pt_ekey; unsigned long long pc = 0; while((pc + STATE_LEN) < mlen){ if(enc_dec == ENC){ // encryption xor_bytes(es, pt+pc, STATE_LEN); pstate2("After xoring message block:", es); memcpy(ct+pc, es, STATE_LEN); } else{ // decryption xor_bytes2(pt+pc, ct+pc, es, STATE_LEN); pstate2("After xoring ciphertext block:", es); memcpy(es, ct+pc, STATE_LEN); } xor_bytes(ts, es, STATE_LEN); pstate2("tag state:", ts); pstate2("Enc:", NULL); AES_encrypt(ts, ts, ekey); /* apply fix1 */ es[0] |= 0x80; pstate2("After applying fix1:", es); pstate2("Enc:", NULL); AES_encrypt(es, es, ekey); pc += STATE_LEN; } /* process the last block */ unsigned long long lastblocklen = mlen - pc; if(lastblocklen > 0){ if(enc_dec == ENC){ // encryption xor_bytes(es, pt+pc, lastblocklen); pstate2("After xoring last partial message block:", es); memcpy(ct+pc, es, lastblocklen); } else{ // decryption xor_bytes2(pt+pc, ct+pc, es, lastblocklen); pstate2("After xoring last partial ciphertext block:", es); memcpy(es, ct+pc, lastblocklen); } xor_bytes(ts, es, lastblocklen); pstate2("tag state:", ts); pstate2("Enc:", NULL); AES_encrypt(ts, ts, ekey); } /* encode the adlen and process */ unsigned long long t_adlen = mlen; unsigned long long i; for(i = 0; i < sizeof(unsigned long long); i++) { ts[STATE_LEN-1-i] ^= t_adlen & 0xff; t_adlen >>= 8; } pstate2("After xoring the legnth of message:", ts); g(ts); pstate2("After applying g:", ts); pstate2("Enc:", NULL); AES_encrypt(ts, ts, ekey); memcpy(tag, ts, tlen); return SUCCESS; }