2010年9月13日 星期一

iproute2 xfrm state command

這是我用來手動新增(test) ipsec的方法,當然還要配合policy
ip xfrm state add \
   src 172.21.46.133 dst 172.21.33.235 \
   proto esp spi 0xc1764476 mode tunnel \
   auth md5 0xbde367f6722286d104212c864d3041ff \
   enc blowfish \
 0xb860a53627435c27c5862ebf7e2e2de15e2fd2786db612eff0ce4b181a9373c34dd1b6ca17b1ffb2d118a575b9f8a9aa865783500b2cd38a

ip xfrm stat delete src 172.21.46.133 dst 172.21.33.235 proto esp spi 0xc1764476

 也可以用sha1加aes
ip xfrm state add src 172.21.46.131 dst 172.21.33.235  proto esp spi 0x4db377c8 reqid 16385 mode tunnel  auth sha1 0xe0a21cb441a0790188f8d5a7573608ae1e75af07 enc aes 0x86e4685642435deb2b53bee6c23723974d0207a4abed037c5028a310ef355a6e

ip xfrm state delete src 172.21.46.131 dst 172.21.33.235  proto esp spi 0x4db377c8
twofish
ip xfrm state add src 172.21.46.131 dst 172.21.33.235  proto esp spi 0x4db377c8 reqid 16385 mode tunnel  auth sha1 0xe0a21cb441a0790188f8d5a7573608ae1e75af07 enc twofish 0x86e4685642435deb2b53bee6c23723974d0207a4abed037c5028a310ef355a6e

ip xfrm state delete src 172.21.46.131 dst 172.21.33.235  proto esp spi 0x4db377c8
IPSec manual mode by iproute2
ip xfrm st add src 172.21.46.131 dst 172.21.33.235 proto esp spi 0x12345678 mode tunnel auth md5 0xbde367f6722286d104212c864d3041ff  enc aes 0xf82bbcccc0e01308e9a8edba1f2c058be3af44bfde5c26657d4a6609ca488ac2

----------------------------------------------------------------------------------------------

其它可以參考的url
http://lwn.net/Articles/375829/
http://osdir.com/ml/linux.kernel.cryptoapi/2008-04/msg00017.html

[lho@svdclab161 sec]$ cat ip-start-transport-ccm
#!/bin/sh

NODE=$1

echo "Starting IPSec transport mode using CCM..."

./ip xfrm policy flush
./ip xfrm state flush
#
# SA
./ip xfrm state add src 10.66.21.164 dst 10.66.21.166 proto esp spi
0x201 mode transport aead "rfc4309(ccm(aes))"
0x0102037aeaca3f87d060a12f4a4487d5a5c335 96
./ip xfrm state add src 10.66.21.166 dst 10.66.21.164 proto esp spi
0x301 mode transport aead "rfc4309(ccm(aes))"
0x010203f6ddb555acfd9d77b03ea3843f265325 96
#
# Policy
if [ "${NODE}" = "A" ]; then
./ip xfrm policy add dir out src 10.66.21.164 dst 10.66.21.166
tmpl proto esp mode transport
./ip xfrm policy add dir in src 10.66.21.166 dst 10.66.21.164
tmpl proto esp mode transport
fi
if [ "${NODE}" = "B" ]; then
./ip xfrm policy add dir in src 10.66.21.164 dst 10.66.21.166
tmpl proto esp mode transport
./ip xfrm policy add dir out src 10.66.21.166 dst 10.66.21.164
tmpl proto esp mode transport
fi

[lho@svdclab161 sec]$ cat ip-start-transport-gcm
#!/bin/sh

NODE=$1

echo "Starting IPSec transport mode using GCM..."

./ip xfrm policy flush
./ip xfrm state flush
#
# SA
./ip xfrm state add src 10.66.21.164 dst 10.66.21.166 proto esp spi
0x201 mode transport aead "rfc4106(gcm(aes))"
0x010203047aeaca3f87d060a12f4a4487d5a5c335 96
./ip xfrm state add src 10.66.21.166 dst 10.66.21.164 proto esp spi
0x301 mode transport aead "rfc4106(gcm(aes))"
0x01020304f6ddb555acfd9d77b03ea3843f265325 96
#
# Policy
if [ "${NODE}" = "A" ]; then
./ip xfrm policy add dir out src 10.66.21.164 dst 10.66.21.166
tmpl proto esp mode transport
./ip xfrm policy add dir in src 10.66.21.166 dst 10.66.21.164
tmpl proto esp mode transport
fi
if [ "${NODE}" = "B" ]; then
./ip xfrm policy add dir in src 10.66.21.164 dst 10.66.21.166
tmpl proto esp mode transport
./ip xfrm policy add dir out src 10.66.21.166 dst 10.66.21.164
tmpl proto esp mode transport
fi

2010年9月3日 星期五

PF_KEYv2 to cipher support internal(二)

這次,我從一個crypto_null.ko的crypto module開始
如同其名,這是一個不做任何事情的cihper
Kernel version 2.6.10

crypto/crypto_null.c
145 static int __init crypto_null_mod_init(void)
146 {
147         int ret = 0;
148
149         ret = crypto_register_alg(&cipher_null);
150         if (ret < 0)
151                 goto out;
152
153         ret = crypto_register_alg(&skcipher_null);
154         if (ret < 0)
155                 goto out_unregister_cipher;
156
157         ret = crypto_register_alg(&digest_null);
158         if (ret < 0)
159                 goto out_unregister_skcipher;
160
161         ret = crypto_register_alg(&compress_null);
162         if (ret < 0)
163                 goto out_unregister_digest
crypto_register_alg will add struct list_head crypto_register_alg.
107 static struct crypto_alg cipher_null = {
108         .cra_name               =       "cipher_null",
109         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
110         .cra_blocksize          =       NULL_BLOCK_SIZE,
111         .cra_ctxsize            =       0,
112         .cra_module             =       THIS_MODULE,
113         .cra_list               =       LIST_HEAD_INIT(cipher_null.cra_list),
114         .cra_u                  =       { .cipher = {
115         .cia_min_keysize        =       NULL_KEY_SIZE,
116         .cia_max_keysize        =       NULL_KEY_SIZE,
117         .cia_setkey             =       null_setkey,
118         .cia_encrypt            =       null_crypt,
119         .cia_decrypt            =       null_crypt } }
120 };
Both of cia_encrypt,cia_decrypt do nothing just call null_crypt

55 static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 56 {
 57         memcpy(dst, src, NULL_BLOCK_SIZE);
 58 }
But in blockcipher is different
122 static struct crypto_alg skcipher_null = {
123         .cra_name               =       "ecb(cipher_null)",
124         .cra_driver_name        =       "ecb-cipher_null",
125         .cra_priority           =       100,
126         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
127         .cra_blocksize          =       NULL_BLOCK_SIZE,
128         .cra_type               =       &crypto_blkcipher_type,
129         .cra_ctxsize            =       0,
130         .cra_module             =       THIS_MODULE,
131         .cra_list               =       LIST_HEAD_INIT(skcipher_null.cra_list),
132         .cra_u                  =       { .blkcipher = {
133         .min_keysize            =       NULL_KEY_SIZE,
134         .max_keysize            =       NULL_KEY_SIZE,
135         .ivsize                 =       NULL_IV_SIZE,
136         .setkey                 =       null_setkey,
137         .encrypt                =       skcipher_null_crypt,
138         .decrypt                =       skcipher_null_crypt } }
139 };

Blockcipher encrypt/decrypt有些不同其中,
(1).  首先inital一個struct blkcipher_walk 
        來記錄src 和dststruct scatterlist (一般這是和platform的dma有關)
            參考: http://lwn.net/Articles/263343/
                      http://lwn.net/Articles/256368/
(2). blkcipher_walk_virt用來

 60 static int skcipher_null_crypt(struct blkcipher_desc *desc,
 61                                struct scatterlist *dst,
 62                                struct scatterlist *src, unsigned int nbytes)
 63 {
 64         struct blkcipher_walk walk;
 65         int err;
 66
 67         blkcipher_walk_init(&walk, dst, src, nbytes);
 68         err = blkcipher_walk_virt(desc, &walk);
 69
 70         while (walk.nbytes) {
 71                 if (walk.src.virt.addr != walk.dst.virt.addr)
 72                         memcpy(walk.dst.virt.addr, walk.src.virt.addr,
 73                                walk.nbytes);
 74                 err = blkcipher_walk_done(desc, &walk, 0);
 75         }
 76
 77         return err;
 78 }
 79


blkcipher_walk describes the relationship of  physical / virtual address whare raw date stored in.
include/crypto/algapi.h
 65 struct scatter_walk {
 66         struct scatterlist *sg;
 67         unsigned int offset;
 68 };
The struct scatterlist is platform depend.
eg: arch/mips/include/asm/scatterlist.h
struct scatterlist {
#ifdef CONFIG_DEBUG_SG
        unsigned long   sg_magic;
#endif
        unsigned long   page_link;
        unsigned int    offset;
        dma_addr_t      dma_address;
        unsigned int    length;
};
 70 struct blkcipher_walk {
 71         union {
 72                 struct {
 73                         struct page *page;
 74                         unsigned long offset;
 75                 } phys;
 76
 77                 struct {
 78                         u8 *page;
 79                         u8 *addr;
 80                 } virt;
 81         } src, dst;
 82
 83         struct scatter_walk in;
 84         unsigned int nbytes;
 85
 86         struct scatter_walk out;
 87         unsigned int total;
 88
 89         void *page;
 90         u8 *buffer;
 91         u8 *iv;
 92
 93         int flags;
 94         unsigned int blocksize;
 95 };

再舉個(VIA PadLock hardware crypto engine)例子
drivers/crypto/padlock-aes.c
255 static int ecb_aes_encrypt(struct blkcipher_desc *desc,
256                            struct scatterlist *dst, struct scatterlist *src,
257                            unsigned int nbytes)
258 {
259         struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
260         struct blkcipher_walk walk;
261         int err;
262         int ts_state;
263
264         padlock_reset_key();
265
266         blkcipher_walk_init(&walk, dst, src, nbytes);
267         err = blkcipher_walk_virt(desc, &walk);
268
269         ts_state = irq_ts_save();
270         while ((nbytes = walk.nbytes)) {
271                 padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,
272                                    ctx->E, &ctx->cword.encrypt,
273                                    nbytes / AES_BLOCK_SIZE);
274                 nbytes &= AES_BLOCK_SIZE - 1;
275                 err = blkcipher_walk_done(desc, &walk, nbytes);
276         }
277         irq_ts_restore(ts_state);
278
279         return err;
280 }

再來看一下cipher_alg這個structure, 其中rca_u會根據不同的cipher:(eg: crypto/hash/digest)
在register時inital相對應的methods

linux/crypto.h
 322 struct crypto_alg {
 323         struct list_head cra_list;
 324         struct list_head cra_users;
 325
 326         u32 cra_flags;
 327         unsigned int cra_blocksize;
 328         unsigned int cra_ctxsize;
 329         unsigned int cra_alignmask;
 330
 331         int cra_priority;
 332         atomic_t cra_refcnt;
 333
 334         char cra_name[CRYPTO_MAX_ALG_NAME];
 335         char cra_driver_name[CRYPTO_MAX_ALG_NAME];
 336
 337         const struct crypto_type *cra_type;
 338
 339         union {
 340                 struct ablkcipher_alg ablkcipher;
 341                 struct aead_alg aead;
 342                 struct blkcipher_alg blkcipher;
 343                 struct cipher_alg cipher;
 344                 struct digest_alg digest;
 345                 struct hash_alg hash;
 346                 struct ahash_alg ahash;
 347                 struct compress_alg compress;
 348                 struct rng_alg rng;
 349         } cra_u;
 350
 351         int (*cra_init)(struct crypto_tfm *tfm);
 352         void (*cra_exit)(struct crypto_tfm *tfm);
 353         void (*cra_destroy)(struct crypto_alg *alg);
 354
 355         struct module *cra_module;
 356 };