X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fxfrm%2Fxfrm_algo.c;h=f1cf3402e75c9aa6c8b242674133b546d0190fad;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=0612ecbc276458551c4bdf8ee1df79895b51cde6;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 0612ecbc2..f1cf3402e 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c @@ -9,10 +9,10 @@ * any later version. */ -#include #include #include #include +#include #include #if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE) #include @@ -30,7 +30,8 @@ */ static struct xfrm_algo_desc aalg_list[] = { { - .name = "digest_null", + .name = "hmac(digest_null)", + .compat = "digest_null", .uinfo = { .auth = { @@ -47,7 +48,8 @@ static struct xfrm_algo_desc aalg_list[] = { } }, { - .name = "md5", + .name = "hmac(md5)", + .compat = "md5", .uinfo = { .auth = { @@ -64,7 +66,8 @@ static struct xfrm_algo_desc aalg_list[] = { } }, { - .name = "sha1", + .name = "hmac(sha1)", + .compat = "sha1", .uinfo = { .auth = { @@ -81,7 +84,8 @@ static struct xfrm_algo_desc aalg_list[] = { } }, { - .name = "sha256", + .name = "hmac(sha256)", + .compat = "sha256", .uinfo = { .auth = { @@ -98,7 +102,8 @@ static struct xfrm_algo_desc aalg_list[] = { } }, { - .name = "ripemd160", + .name = "hmac(ripemd160)", + .compat = "ripemd160", .uinfo = { .auth = { @@ -114,11 +119,29 @@ static struct xfrm_algo_desc aalg_list[] = { .sadb_alg_maxbits = 160 } }, +{ + .name = "xcbc(aes)", + + .uinfo = { + .auth = { + .icv_truncbits = 96, + .icv_fullbits = 128, + } + }, + + .desc = { + .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC, + .sadb_alg_ivlen = 0, + .sadb_alg_minbits = 128, + .sadb_alg_maxbits = 128 + } +}, }; static struct xfrm_algo_desc ealg_list[] = { { - .name = "cipher_null", + .name = "ecb(cipher_null)", + .compat = "cipher_null", .uinfo = { .encr = { @@ -135,7 +158,8 @@ static struct xfrm_algo_desc ealg_list[] = { } }, { - .name = "des", + .name = "cbc(des)", + .compat = "des", .uinfo = { .encr = { @@ -152,7 +176,8 @@ static struct xfrm_algo_desc ealg_list[] = { } }, { - .name = "des3_ede", + .name = "cbc(des3_ede)", + .compat = "des3_ede", .uinfo = { .encr = { @@ -169,7 +194,8 @@ static struct xfrm_algo_desc ealg_list[] = { } }, { - .name = "cast128", + .name = "cbc(cast128)", + .compat = "cast128", .uinfo = { .encr = { @@ -186,7 +212,8 @@ static struct xfrm_algo_desc ealg_list[] = { } }, { - .name = "blowfish", + .name = "cbc(blowfish)", + .compat = "blowfish", .uinfo = { .encr = { @@ -203,7 +230,8 @@ static struct xfrm_algo_desc ealg_list[] = { } }, { - .name = "aes", + .name = "cbc(aes)", + .compat = "aes", .uinfo = { .encr = { @@ -220,7 +248,8 @@ static struct xfrm_algo_desc ealg_list[] = { } }, { - .name = "serpent", + .name = "cbc(serpent)", + .compat = "serpent", .uinfo = { .encr = { @@ -237,7 +266,8 @@ static struct xfrm_algo_desc ealg_list[] = { } }, { - .name = "twofish", + .name = "cbc(twofish)", + .compat = "twofish", .uinfo = { .encr = { @@ -315,6 +345,7 @@ struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id) } return NULL; } +EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid); struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) { @@ -330,6 +361,7 @@ struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id) } return NULL; } +EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid); struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) { @@ -345,60 +377,62 @@ struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id) } return NULL; } +EXPORT_SYMBOL_GPL(xfrm_calg_get_byid); -struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name) +static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, + int entries, u32 type, u32 mask, + char *name, int probe) { - int i; + int i, status; if (!name) return NULL; - for (i=0; i < aalg_entries(); i++) { - if (strcmp(name, aalg_list[i].name) == 0) { - if (aalg_list[i].available) - return &aalg_list[i]; - else - break; - } - } - return NULL; -} + for (i = 0; i < entries; i++) { + if (strcmp(name, list[i].name) && + (!list[i].compat || strcmp(name, list[i].compat))) + continue; -struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name) -{ - int i; + if (list[i].available) + return &list[i]; - if (!name) - return NULL; + if (!probe) + break; - for (i=0; i < ealg_entries(); i++) { - if (strcmp(name, ealg_list[i].name) == 0) { - if (ealg_list[i].available) - return &ealg_list[i]; - else - break; - } + status = crypto_has_alg(list[i].name, type, + mask | CRYPTO_ALG_ASYNC); + if (!status) + break; + + list[i].available = status; + return &list[i]; } return NULL; } -struct xfrm_algo_desc *xfrm_calg_get_byname(char *name) +struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe) { - int i; + return xfrm_get_byname(aalg_list, aalg_entries(), + CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK, + name, probe); +} +EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname); - if (!name) - return NULL; +struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe) +{ + return xfrm_get_byname(ealg_list, ealg_entries(), + CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK, + name, probe); +} +EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname); - for (i=0; i < calg_entries(); i++) { - if (strcmp(name, calg_list[i].name) == 0) { - if (calg_list[i].available) - return &calg_list[i]; - else - break; - } - } - return NULL; +struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe) +{ + return xfrm_get_byname(calg_list, calg_entries(), + CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK, + name, probe); } +EXPORT_SYMBOL_GPL(xfrm_calg_get_byname); struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx) { @@ -407,6 +441,7 @@ struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx) return &aalg_list[idx]; } +EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx); struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx) { @@ -415,14 +450,7 @@ struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx) return &ealg_list[idx]; } - -struct xfrm_algo_desc *xfrm_calg_get_byidx(unsigned int idx) -{ - if (idx >= calg_entries()) - return NULL; - - return &calg_list[idx]; -} +EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx); /* * Probe for the availability of crypto algorithms, and set the available @@ -437,24 +465,28 @@ void xfrm_probe_algs(void) BUG_ON(in_softirq()); for (i = 0; i < aalg_entries(); i++) { - status = crypto_alg_available(aalg_list[i].name, 0); + status = crypto_has_hash(aalg_list[i].name, 0, + CRYPTO_ALG_ASYNC); if (aalg_list[i].available != status) aalg_list[i].available = status; } for (i = 0; i < ealg_entries(); i++) { - status = crypto_alg_available(ealg_list[i].name, 0); + status = crypto_has_blkcipher(ealg_list[i].name, 0, + CRYPTO_ALG_ASYNC); if (ealg_list[i].available != status) ealg_list[i].available = status; } for (i = 0; i < calg_entries(); i++) { - status = crypto_alg_available(calg_list[i].name, 0); + status = crypto_has_comp(calg_list[i].name, 0, + CRYPTO_ALG_ASYNC); if (calg_list[i].available != status) calg_list[i].available = status; } #endif } +EXPORT_SYMBOL_GPL(xfrm_probe_algs); int xfrm_count_auth_supported(void) { @@ -465,6 +497,7 @@ int xfrm_count_auth_supported(void) n++; return n; } +EXPORT_SYMBOL_GPL(xfrm_count_auth_supported); int xfrm_count_enc_supported(void) { @@ -475,14 +508,16 @@ int xfrm_count_enc_supported(void) n++; return n; } +EXPORT_SYMBOL_GPL(xfrm_count_enc_supported); /* Move to common area: it is shared with AH. */ -void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, - int offset, int len, icv_update_fn_t icv_update) +int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, + int offset, int len, icv_update_fn_t icv_update) { int start = skb_headlen(skb); int i, copy = start - offset; + int err; struct scatterlist sg; /* Checksum header. */ @@ -494,10 +529,12 @@ void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; sg.length = copy; - icv_update(tfm, &sg, 1); + err = icv_update(desc, &sg, copy); + if (unlikely(err)) + return err; if ((len -= copy) == 0) - return; + return 0; offset += copy; } @@ -517,10 +554,12 @@ void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, sg.offset = frag->page_offset + offset-start; sg.length = copy; - icv_update(tfm, &sg, 1); + err = icv_update(desc, &sg, copy); + if (unlikely(err)) + return err; if (!(len -= copy)) - return; + return 0; offset += copy; } start = end; @@ -538,17 +577,21 @@ void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, if ((copy = end - offset) > 0) { if (copy > len) copy = len; - skb_icv_walk(list, tfm, offset-start, copy, icv_update); + err = skb_icv_walk(list, desc, offset-start, + copy, icv_update); + if (unlikely(err)) + return err; if ((len -= copy) == 0) - return; + return 0; offset += copy; } start = end; } } - if (len) - BUG(); + BUG_ON(len); + return 0; } +EXPORT_SYMBOL_GPL(skb_icv_walk); #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE) @@ -615,8 +658,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) start = end; } } - if (len) - BUG(); + BUG_ON(len); return elt; } EXPORT_SYMBOL_GPL(skb_to_sgvec); @@ -703,7 +745,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) return -ENOMEM; if (skb1->sk) - skb_set_owner_w(skb, skb1->sk); + skb_set_owner_w(skb2, skb1->sk); /* Looking around. Are we still alive? * OK, link new skb, drop old one */