Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 75943
b: refs/heads/master
c: 6160b28
h: refs/heads/master
i:
  75941: 4cff6a0
  75939: ba249f0
  75935: e7c093d
v: v3
  • Loading branch information
Herbert Xu committed Jan 10, 2008
1 parent 0399d6f commit ecde7eb
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 130 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8df213d9b520a4b58b7a8f7f2200324d4e40363d
refs/heads/master: 6160b289929c0b622e64aa36106d8e6e53fcd826
68 changes: 40 additions & 28 deletions trunk/crypto/gcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct crypto_gcm_ghash_ctx {

struct crypto_gcm_req_priv_ctx {
u8 auth_tag[16];
u8 iauth_tag[16];
u8 counter[16];
struct crypto_gcm_ghash_ctx ghash;
};
Expand Down Expand Up @@ -89,6 +90,9 @@ static void crypto_gcm_ghash_update_sg(struct crypto_gcm_ghash_ctx *ctx,
u8 *src;
int n;

if (!len)
return;

scatterwalk_start(&walk, sg);

while (len) {
Expand Down Expand Up @@ -211,9 +215,10 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
}

static int crypto_gcm_init_crypt(struct ablkcipher_request *ablk_req,
struct aead_request *req,
void (*done)(struct crypto_async_request *,
int))
struct aead_request *req,
unsigned int cryptlen,
void (*done)(struct crypto_async_request *,
int))
{
struct crypto_aead *aead = crypto_aead_reqtfm(req);
struct crypto_gcm_ctx *ctx = crypto_aead_ctx(aead);
Expand All @@ -228,7 +233,7 @@ static int crypto_gcm_init_crypt(struct ablkcipher_request *ablk_req,
ablkcipher_request_set_callback(ablk_req, aead_request_flags(req),
done, req);
ablkcipher_request_set_crypt(ablk_req, req->src, req->dst,
req->cryptlen, counter);
cryptlen, counter);

err = crypto_gcm_encrypt_counter(aead, auth_tag, 0, req->iv);
if (err)
Expand All @@ -239,18 +244,16 @@ static int crypto_gcm_init_crypt(struct ablkcipher_request *ablk_req,

crypto_gcm_ghash_init(ghash, flags, ctx->gf128);

if (req->assoclen) {
crypto_gcm_ghash_update_sg(ghash, req->assoc, req->assoclen);
crypto_gcm_ghash_flush(ghash);
}
crypto_gcm_ghash_update_sg(ghash, req->assoc, req->assoclen);
crypto_gcm_ghash_flush(ghash);

out:
return err;
}

static void crypto_gcm_encrypt_done(struct crypto_async_request *areq, int err)
static int crypto_gcm_hash(struct aead_request *req)
{
struct aead_request *req = areq->data;
struct crypto_aead *aead = crypto_aead_reqtfm(req);
struct crypto_gcm_req_priv_ctx *pctx = aead_request_ctx(req);
u8 *auth_tag = pctx->auth_tag;
struct crypto_gcm_ghash_ctx *ghash = &pctx->ghash;
Expand All @@ -259,33 +262,38 @@ static void crypto_gcm_encrypt_done(struct crypto_async_request *areq, int err)
crypto_gcm_ghash_final_xor(ghash, req->assoclen, req->cryptlen,
auth_tag);

scatterwalk_map_and_copy(auth_tag, req->dst, req->cryptlen,
crypto_aead_authsize(aead), 1);
return 0;
}

static void crypto_gcm_encrypt_done(struct crypto_async_request *areq, int err)
{
struct aead_request *req = areq->data;

if (!err)
err = crypto_gcm_hash(req);

aead_request_complete(req, err);
}

static int crypto_gcm_encrypt(struct aead_request *req)
{
struct ablkcipher_request abreq;
struct crypto_gcm_req_priv_ctx *pctx = aead_request_ctx(req);
u8 *auth_tag = pctx->auth_tag;
struct crypto_gcm_ghash_ctx *ghash = &pctx->ghash;
int err = 0;

err = crypto_gcm_init_crypt(&abreq, req, crypto_gcm_encrypt_done);
err = crypto_gcm_init_crypt(&abreq, req, req->cryptlen,
crypto_gcm_encrypt_done);
if (err)
return err;

if (req->cryptlen) {
err = crypto_ablkcipher_encrypt(&abreq);
if (err)
return err;

crypto_gcm_ghash_update_sg(ghash, req->dst, req->cryptlen);
}

crypto_gcm_ghash_final_xor(ghash, req->assoclen, req->cryptlen,
auth_tag);

return err;
return crypto_gcm_hash(req);
}

static void crypto_gcm_decrypt_done(struct crypto_async_request *areq, int err)
Expand All @@ -296,25 +304,29 @@ static void crypto_gcm_decrypt_done(struct crypto_async_request *areq, int err)
static int crypto_gcm_decrypt(struct aead_request *req)
{
struct ablkcipher_request abreq;
struct crypto_aead *aead = crypto_aead_reqtfm(req);
struct crypto_gcm_req_priv_ctx *pctx = aead_request_ctx(req);
u8 *auth_tag = pctx->auth_tag;
u8 *iauth_tag = pctx->iauth_tag;
struct crypto_gcm_ghash_ctx *ghash = &pctx->ghash;
u8 tag[16];
unsigned int cryptlen = req->cryptlen;
unsigned int authsize = crypto_aead_authsize(aead);
int err;

if (!req->cryptlen)
if (cryptlen < authsize)
return -EINVAL;
cryptlen -= authsize;

memcpy(tag, auth_tag, 16);
err = crypto_gcm_init_crypt(&abreq, req, crypto_gcm_decrypt_done);
err = crypto_gcm_init_crypt(&abreq, req, cryptlen,
crypto_gcm_decrypt_done);
if (err)
return err;

crypto_gcm_ghash_update_sg(ghash, req->src, req->cryptlen);
crypto_gcm_ghash_final_xor(ghash, req->assoclen, req->cryptlen,
auth_tag);
crypto_gcm_ghash_update_sg(ghash, req->src, cryptlen);
crypto_gcm_ghash_final_xor(ghash, req->assoclen, cryptlen, auth_tag);

if (memcmp(tag, auth_tag, 16))
scatterwalk_map_and_copy(iauth_tag, req->src, cryptlen, authsize, 0);
if (memcmp(iauth_tag, auth_tag, authsize))
return -EINVAL;

return crypto_ablkcipher_decrypt(&abreq);
Expand Down
44 changes: 16 additions & 28 deletions trunk/crypto/tcrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
struct scatterlist asg[8];
const char *e;
struct tcrypt_result result;
unsigned int authsize;

if (enc == ENCRYPT)
e = "encryption";
Expand Down Expand Up @@ -265,6 +266,8 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
return;
}

authsize = crypto_aead_authsize(tfm);

req = aead_request_alloc(tfm, GFP_KERNEL);
if (!req) {
printk(KERN_INFO "failed to allocate request for %s\n", algo);
Expand Down Expand Up @@ -296,7 +299,7 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
}

sg_init_one(&sg[0], aead_tv[i].input,
aead_tv[i].ilen);
aead_tv[i].ilen + (enc ? authsize : 0));

sg_init_one(&asg[0], aead_tv[i].assoc,
aead_tv[i].alen);
Expand All @@ -307,13 +310,9 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,

aead_request_set_assoc(req, asg, aead_tv[i].alen);

if (enc) {
ret = crypto_aead_encrypt(req);
} else {
memcpy(req->__ctx, aead_tv[i].tag,
aead_tv[i].tlen);
ret = crypto_aead_decrypt(req);
}
ret = enc ?
crypto_aead_encrypt(req) :
crypto_aead_decrypt(req);

switch (ret) {
case 0:
Expand All @@ -335,16 +334,10 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,

q = kmap(sg_page(&sg[0])) + sg[0].offset;
hexdump(q, aead_tv[i].rlen);
printk(KERN_INFO "auth tag: ");
hexdump((unsigned char *)req->__ctx, aead_tv[i].tlen);

printk(KERN_INFO "enc/dec: %s\n",
memcmp(q, aead_tv[i].result,
aead_tv[i].rlen) ? "fail" : "pass");

printk(KERN_INFO "auth tag: %s\n",
memcmp(req->__ctx, aead_tv[i].tag,
aead_tv[i].tlen) ? "fail" : "pass");
}
}

Expand Down Expand Up @@ -381,6 +374,9 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
aead_tv[i].tap[k]);
}

if (enc)
sg[k - 1].length += authsize;

sg_init_table(asg, aead_tv[i].anp);
for (k = 0, temp = 0; k < aead_tv[i].anp; k++) {
memcpy(&axbuf[IDX[k]],
Expand All @@ -397,13 +393,9 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,

aead_request_set_assoc(req, asg, aead_tv[i].alen);

if (enc) {
ret = crypto_aead_encrypt(req);
} else {
memcpy(req->__ctx, aead_tv[i].tag,
aead_tv[i].tlen);
ret = crypto_aead_decrypt(req);
}
ret = enc ?
crypto_aead_encrypt(req) :
crypto_aead_decrypt(req);

switch (ret) {
case 0:
Expand All @@ -429,17 +421,13 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
hexdump(q, aead_tv[i].tap[k]);
printk(KERN_INFO "%s\n",
memcmp(q, aead_tv[i].result + temp,
aead_tv[i].tap[k]) ?
aead_tv[i].tap[k] -
(k < aead_tv[i].np - 1 || enc ?
0 : authsize)) ?
"fail" : "pass");

temp += aead_tv[i].tap[k];
}
printk(KERN_INFO "auth tag: ");
hexdump((unsigned char *)req->__ctx, aead_tv[i].tlen);

printk(KERN_INFO "auth tag: %s\n",
memcmp(req->__ctx, aead_tv[i].tag,
aead_tv[i].tlen) ? "fail" : "pass");
}
}

Expand Down
Loading

0 comments on commit ecde7eb

Please sign in to comment.