static int crypto_gcm_decrypt(struct aead_request *req) { struct crypto_aead *aead = crypto_aead_reqtfm(req); struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); struct ablkcipher_request *abreq = &pctx->u.abreq; struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; unsigned int authsize = crypto_aead_authsize(aead); unsigned int cryptlen = req->cryptlen; int err; if (cryptlen < authsize) return -EINVAL; cryptlen -= authsize; gctx->src = req->src; gctx->cryptlen = cryptlen; gctx->complete = gcm_dec_hash_done; err = gcm_hash(req, pctx); if (err) return err; ablkcipher_request_set_callback(abreq, aead_request_flags(req), gcm_decrypt_done, req); crypto_gcm_init_crypt(abreq, req, cryptlen); err = crypto_ablkcipher_decrypt(abreq); if (err) return err; return crypto_gcm_verify(req, pctx); }
static int crypto_gcm_encrypt(struct aead_request *req) { struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); struct ablkcipher_request *abreq = &pctx->u.abreq; struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; int err; crypto_gcm_init_crypt(abreq, req, req->cryptlen); ablkcipher_request_set_callback(abreq, aead_request_flags(req), gcm_encrypt_done, req); gctx->src = req->dst; gctx->cryptlen = req->cryptlen; gctx->complete = gcm_enc_hash_done; err = crypto_ablkcipher_encrypt(abreq); if (err) return err; err = gcm_hash(req, pctx); if (err) return err; crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); gcm_enc_copy_hash(req, pctx); return 0; }
static void gcm_encrypt_done(struct crypto_async_request *areq, int err) { struct aead_request *req = areq->data; struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); if (!err) { err = gcm_hash(req, pctx); if (err == -EINPROGRESS || err == -EBUSY) return; } gcm_enc_hash_done(areq, err); }
static void gcm_encrypt_done(struct crypto_async_request *areq, int err) { struct aead_request *req = areq->data; struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); if (!err) { err = gcm_hash(req, pctx); if (err == -EINPROGRESS || err == -EBUSY) return; else if (!err) { crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); gcm_enc_copy_hash(req, pctx); } } aead_request_complete(req, err); }
int main(int argc, char **argv) { uint8 buf[4096]; uint8 tag[GCM_BLOCK_SZ]; status_t res; ENABLE_DEBUG; BEGINT(0); memcpy(buf, p0, plen0); aes_gcm_encrypt(k0, klen0, n0, nlen0, a0, alen0, buf, plen0, tag, sizeof(tag)); res = !memcmp(tag, t0, tlen0) ? OK : ERR; if (res != OK) TAG_ERR(res, t0, tag, tlen0); ENDT(0, res); BEGINT(1); memcpy(buf, p1, plen1); aes_gcm_mac(k1, klen1, n1, nlen1, a1, alen1, buf, plen1, tag, sizeof(tag)); res = !memcmp(tag, t1, tlen1) ? OK : ERR; if (res != OK) TAG_ERR(res, t1, tag, tlen1); ENDT(1, res); BEGINT(2); memcpy(buf, p1, plen1); aes_gcm_encrypt(k1, klen1, n1, nlen1, a1, alen1, buf, plen1, tag, sizeof(tag)); res = !memcmp(c1, buf, plen1) ? OK : ERR; if (res != OK) { CTXT_ERR(res, c1, buf, plen1); } else { res = !memcmp(tag, t1, tlen1) ? OK : ERR; if (res != OK) TAG_ERR(res, t1, tag, tlen1); } ENDT(2, res); BEGINT(3); memcpy(buf, p3, plen3); aes_gcm_encrypt(k3, klen3, n3, nlen3, a3, alen3, buf, plen3, tag, sizeof(tag)); res = !memcmp(c3, buf, plen3) ? OK : ERR; if (res != OK) { CTXT_ERR(res, c3, buf, plen3); } else { res = !memcmp(tag, t3, tlen3) ? OK : ERR; if (res != OK) TAG_ERR(res, t3, tag, tlen3); } ENDT(3, res); #ifdef HAVE_GCM_HASH BEGINT(4); gcm_hash(hk4, ac4, aclen4, buf, TRUE); res = !memcmp(hac4, buf, haclen4) ? OK : ERR; if (res != OK) TAG_ERR(res, hac4, buf, haclen4); ENDT(4, res); #endif BEGINT(5); memcpy(buf, p5, plen5); aes_gcm_encrypt(k5, klen5, n5, nlen5, a5, alen5, buf, plen5, tag, sizeof(tag)); res = !memcmp(c5, buf, plen5) ? OK : ERR; if (res != OK) { CTXT_ERR(res, c5, buf, plen5); } else { res = !memcmp(tag, t5, tlen5) ? OK : ERR; if (res != OK) TAG_ERR(res, t5, tag, tlen5); } ENDT(5, res); BEGINT(6); memcpy(buf, p5, plen5); aes_gcm_encrypt(k5, klen5, n6, nlen6, a5, alen5, buf, plen5, tag, sizeof(tag)); res = !memcmp(c6, buf, plen5) ? OK : ERR; if (res != OK) { CTXT_ERR(res, c6, buf, plen5); } else { res = !memcmp(tag, t6, tlen6) ? OK : ERR; if (res != OK) TAG_ERR(res, t6, tag, tlen6); } ENDT(6, res); BEGINT(7); memcpy(buf, c6, plen5); res = aes_gcm_decrypt(k5, klen5, n6, nlen6, a5, alen5, buf, plen5, t6, tlen6) ? OK : ERR; if (res != OK) { DBG("aes_gcm_decrypt returned error", NULL, 0); } else { res = !memcmp(p5, buf, plen5) ? OK : ERR; if (res != OK) PTXT_ERR(res, p5, buf, plen5); } ENDT(7, res); BEGINT(8); memcpy(buf, p5, plen5); res = aes_gcm_verify(k5, klen5, n6, nlen6, a5, alen5, buf, plen5, t6, tlen6) ? OK : ERR; if (res != OK) { DBG("aes_gcm_verify returned error", NULL, 0); } ENDT(8, res); BEGINT(9); memcpy(buf, p5, plen5); aes_gcm_mac(k5, klen5, n6, nlen6, a5, alen5, buf, plen5, tag, sizeof(tag)); res = !memcmp(tag, t6, tlen6) ? OK : ERR; if (res != OK) TAG_ERR(res, t6, tag, tlen6); ENDT(9, res); BEGINT(10); /* validate encrypt */ memcpy(buf, p10, plen10) ; aes_gcm_encrypt(k10, klen10, n10, nlen10, a10, alen10, buf, plen10, tag, sizeof(tag)); res = !memcmp(c10, buf, plen10) ? OK : ERR; if (res != OK) { CTXT_ERR(res, c10, buf, plen10); } else { res = !memcmp(tag, t10, tlen10) ? OK : ERR; if (res != OK) TAG_ERR(res, t10, tag, tlen10); } /* validate (just) mac */ memcpy(buf, p10, plen10); aes_gcm_mac(k10, klen10, n10, nlen10, a10, alen10, buf, plen10, tag, sizeof(tag)); res = !memcmp(tag, t10, tlen10) ? OK : ERR; if (res != OK) TAG_ERR(res, t10, tag, tlen10); /* validate decrypt */ memcpy(buf, c10, clen10); res = aes_gcm_decrypt(k10, klen10, n10, nlen10, a10, alen10, buf, clen10, t10, tlen10) ? OK : ERR; if (res != OK) { DBG("aes_gcm_decrypt returned error", NULL, 0); } else { res = !memcmp(p10, buf, plen10) ? OK : ERR; if (res != OK) { PTXT_ERR(res, p10, buf, plen10); } } /* validate verify */ memcpy(buf, p10, plen10); res = aes_gcm_verify(k10, klen10, n10, nlen10, a10, alen10, buf, plen10, t10, tlen10) ? OK : ERR; if (res != OK) { DBG("aes_gcm_verify returned error", NULL, 0); } ENDT(10, res); BEGINT(11); /* validate encrypt */ memcpy(buf, p10, plen10) ; aes_gcm_encrypt(k11, klen11, n10, nlen10, a10, alen10, buf, plen10, tag, sizeof(tag)); res = !memcmp(c11, buf, plen10) ? OK : ERR; if (res != OK) { CTXT_ERR(res, c11, buf, plen10); } else { res = !memcmp(tag, t11, tlen11) ? OK : ERR; if (res != OK) TAG_ERR(res, t11, tag, tlen11); } /* validate (just) mac */ memcpy(buf, p10, plen10); aes_gcm_mac(k11, klen11, n10, nlen10, a10, alen10, buf, plen10, tag, sizeof(tag)); res = !memcmp(tag, t11, tlen11) ? OK : ERR; if (res != OK) TAG_ERR(res, t11, tag, tlen11); /* validate decrypt */ memcpy(buf, c11, clen11); res = aes_gcm_decrypt(k11, klen11, n10, nlen10, a10, alen10, buf, clen11, t11, tlen11) ? OK : ERR; if (res != OK) { DBG("aes_gcm_decrypt returned error", NULL, 0); } else { res = !memcmp(p10, buf, plen10) ? OK : ERR; if (res != OK) { PTXT_ERR(res, p10, buf, plen10); } } /* validate verify */ memcpy(buf, p10, plen10); res = aes_gcm_verify(k11, klen11, n10, nlen10, a10, alen10, buf, plen10, t11, tlen11) ? OK : ERR; if (res != OK) { DBG("aes_gcm_verify returned error", NULL, 0); } ENDT(11, res); BEGINT(12); /* validate encrypt */ memcpy(buf, p12, plen12) ; aes_gcm_encrypt(k12, klen12, n12, nlen12, a12, alen12, buf, plen12, tag, sizeof(tag)); res = !memcmp(c12, buf, plen12) ? OK : ERR; if (res != OK) { CTXT_ERR(res, c12, buf, plen12); } else { res = !memcmp(tag, t12, tlen12) ? OK : ERR; if (res != OK) TAG_ERR(res, t12, tag, tlen12); } /* validate (just) mac */ memcpy(buf, p12, plen12); aes_gcm_mac(k12, klen12, n12, nlen12, a12, alen12, buf, plen12, tag, sizeof(tag)); res = !memcmp(tag, t12, tlen12) ? OK : ERR; if (res != OK) TAG_ERR(res, t12, tag, tlen12); /* validate decrypt */ memcpy(buf, c12, clen12); res = aes_gcm_decrypt(k12, klen12, n12, nlen12, a12, alen12, buf, clen12, t12, tlen12) ? OK : ERR; if (res != OK) { DBG("aes_gcm_decrypt returned error", NULL, 0); } else { res = !memcmp(p12, buf, plen12) ? OK : ERR; if (res != OK) { PTXT_ERR(res, p12, buf, plen12); } } /* validate verify */ memcpy(buf, p12, plen12); res = aes_gcm_verify(k12, klen12, n12, nlen12, a12, alen12, buf, plen12, t12, tlen12) ? OK : ERR; if (res != OK) { DBG("aes_gcm_verify returned error", NULL, 0); } ENDT(12, res); BEGINT(13); /* validate encrypt */ memcpy(buf, p12, plen12) ; aes_gcm_encrypt(k13, klen13, n12, nlen12, a12, alen12, buf, plen12, tag, sizeof(tag)); res = !memcmp(c13, buf, plen12) ? OK : ERR; if (res != OK) { CTXT_ERR(res, c13, buf, plen12); } else { res = !memcmp(tag, t13, tlen13) ? OK : ERR; if (res != OK) TAG_ERR(res, t13, tag, tlen13); } /* validate (just) mac */ memcpy(buf, p12, plen12); aes_gcm_mac(k13, klen13, n12, nlen12, a12, alen12, buf, plen12, tag, sizeof(tag)); res = !memcmp(tag, t13, tlen13) ? OK : ERR; if (res != OK) TAG_ERR(res, t13, tag, tlen13); /* validate decrypt */ memcpy(buf, c13, clen13); res = aes_gcm_decrypt(k13, klen13, n12, nlen12, a12, alen12, buf, clen12, t13, tlen13) ? OK : ERR; if (res != OK) { DBG("aes_gcm_decrypt returned error", NULL, 0); } else { res = !memcmp(p12, buf, plen12) ? OK : ERR; if (res != OK) { PTXT_ERR(res, p12, buf, plen12); } } /* validate verify */ memcpy(buf, p12, plen12); res = aes_gcm_verify(k13, klen13, n12, nlen12, a12, alen12, buf, plen12, t13, tlen13) ? OK : ERR; if (res != OK) { DBG("aes_gcm_verify returned error", NULL, 0); } ENDT(13, res); BEGINT(14); /* validate encrypt */ memcpy(buf, p14, plen14) ; aes_gcm_encrypt(k14, klen14, n14, nlen14, a14, alen14, buf, plen14, tag, sizeof(tag)); res = !memcmp(c14, buf, plen14) ? OK : ERR; if (res != OK) { CTXT_ERR(res, c14, buf, plen14); } else { res = !memcmp(tag, t14, tlen14) ? OK : ERR; if (res != OK) TAG_ERR(res, t14, tag, tlen14); } /* validate (just) mac */ memcpy(buf, p14, plen14); aes_gcm_mac(k14, klen14, n14, nlen14, a14, alen14, buf, plen14, tag, sizeof(tag)); res = !memcmp(tag, t14, tlen14) ? OK : ERR; if (res != OK) TAG_ERR(res, t14, tag, tlen14); /* validate decrypt */ memcpy(buf, c14, clen14); res = aes_gcm_decrypt(k14, klen14, n14, nlen14, a14, alen14, buf, clen14, t14, tlen14) ? OK : ERR; if (res != OK) { DBG("aes_gcm_decrypt returned error", NULL, 0); } else { res = !memcmp(p14, buf, plen14) ? OK : ERR; if (res != OK) { PTXT_ERR(res, p14, buf, plen14); } } /* validate verify */ memcpy(buf, p14, plen14); res = aes_gcm_verify(k14, klen14, n14, nlen14, a14, alen14, buf, plen14, t14, tlen14) ? OK : ERR; if (res != OK) { DBG("aes_gcm_verify returned error", NULL, 0); } ENDT(14, res); return 0; }