📄 encaps.c
字号:
/* CIPE - encrypted IP over UDP tunneling encaps.c - do encryption Copyright 1996 Olaf Titz <olaf@bigred.inka.de> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.*//* $Id: encaps.c,v 1.26 2004/03/06 22:16:41 olaf81825 Exp $ */#include "cipe.h"#include <asm/string.h>#include <linux/socket.h>void cipe_cryptpad_iv(unsigned char *buf, int len){ int i=5; do { cipe_cryptpad(buf, len); if (*((__u32 *)buf) & htonl(0x7FFFFFFF)) break; } while (i-->0); if (!i) printk(KERN_CRIT "cipe_cryptpad_iv failed");}void cipe_checkskey(struct cipe *c){ if ((++c->cntskey>MAXBLKS) || (jiffies>c->timeskey)) { /* make the control process send an NK_IND */ cipe_fakenkey(c, NK_REQ); c->timeskey=jiffies+c->tmo_keyxchg; if (c->cntskey>MAXBLKS) c->cntskey-=1000; }}void cipe_checkrkey(struct cipe *c){ if ((c->flags&CIPF_HAVE_RKEY) && ((++c->cntrkey>MAXBLKS*2) || (jiffies>c->timerkey))) { /* make the control process send an NK_REQ */ cipe_fakenkey(c, NK_RREQ); c->flags&=~CIPF_HAVE_RKEY; c->timerkey=jiffies+c->tmo_keyxchg; if (c->cntrkey>MAXBLKS*2) c->cntrkey-=1000; }}void cipe_nodynkey(struct cipe *c){ if (jiffies>c->timerkey) { /* make the control process send an NK_REQ */ cipe_fakenkey(c, NK_RREQ); c->timerkey=jiffies+c->tmo_keyxchg; } dprintk(DEB_CRYPT, (KERN_INFO "%s: missing dynamic key\n", c->dev->name));}/* CBC routines, assuming fixed block size of 8 bytes. */typedef unsigned long part;#define blockSize 8#define partSize (blockSize/sizeof(part))#define partinc(p) ((p)+partSize)static inline void xorbuf(part *dst, const part *src1, const part *src2){ int i; for (i=0; i<partSize; ++i) *dst++=*src1++^*src2++;}static void cbc_encrypt_atomic(struct crypto_tfm *tfm, u8 *out, const u8 *in, int size, const u8 *iv){ register part *inp=(part *)in; register part *outp=(part *)out; part tmp[partSize]; int i=size/blockSize; xorbuf(tmp, (part *)iv, inp); crypto_cipher_encrypt_blk(tfm, (u8 *)outp, (u8 *)&tmp); while (--i>0) { inp=partinc(inp); xorbuf(tmp, outp, inp); outp=partinc(outp); crypto_cipher_encrypt_blk(tfm, (u8 *)outp, (u8 *)&tmp); }}/* NB. This does not work with in==out. It does however work with in==out+blockSize */static void cbc_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in, int size, const u8 *iv){ register part *inp=(part *)in; register part *outp=(part *)out; part tmp[partSize]; int i=size/blockSize; memcpy(tmp, iv, blockSize); while (i-->0) { crypto_cipher_decrypt_blk(tfm, (u8 *)outp, (u8 *)inp); xorbuf(outp, outp, tmp); memcpy(tmp, inp, blockSize); inp=partinc(inp); outp=partinc(outp);#ifdef LINUX_25 if (need_resched()) schedule();#else#ifdef LINUX_21 if (current->need_resched) schedule();#else if (need_resched) schedule();#endif#endif }}/* Calling convention: Buffer includes prepended IV Length includes prepended IV Returned length includes IV and appended protocol stuff*/void cipe_encrypt(struct cipe *c, unsigned char *buf, int *len, int typ){ struct crypto_tfm *key = c->flags&CIPF_HAVE_SKEY ? c->skey : c->key; int ivs = crypto_tfm_alg_ivsize(key); unsigned char p=7-(((*len)+4)&7); /* merge key flag in IV */ if (c->flags&CIPF_HAVE_SKEY) *buf|=0x80; else *buf&=0x7F; /* pad */ cipe_prnpad(buf+(*len), p); (*len)+=p+5; /* set type and crc */ *(buf+(*len)-5)=typ|(p<<4); *((__u32 *)(buf+(*len)-4))=htonl(crc32(0, buf+ivs, (*len)-ivs-4)); buf+=ivs; dprintk(DEB_CRYPT, (KERN_INFO "%s: encrypt typ %d pad %d len %d\n", c->dev->name, typ, p, *len)); cbc_encrypt_atomic(key, buf, buf, (*len)-ivs, buf-ivs); cipe_checkskey(c);}/* Calling convention: Buffer includes IV Length includes IV and protocol stuff Returned packet in buffer has IV overwritten Returned length is pure packet*/unsigned short cipe_decrypt(struct cipe *c, unsigned char *buf, int *len){ unsigned char p; struct crypto_tfm *key; int ivs; if (((*buf)&0x80) && !(c->flags&CIPF_HAVE_RKEY)) { cipe_nodynkey(c); return TW_ERROR; /* can't decrypt - no valid key */ } key=(*buf)&0x80 ? c->rkey : c->key; ivs = crypto_tfm_alg_ivsize(key); (*len)-=ivs; cbc_decrypt(key, buf, buf+ivs, *len, buf); if (*((__u32 *)(buf+(*len)-4)) != htonl(crc32(0, buf, (*len)-4))) { dprintk(DEB_CRYPT, (KERN_INFO "%s: decrypt CRC error\n", c->dev->name)); if (c->flags&CIPF_NOTIFY_DERR) { c->flags&=~CIPF_NOTIFY_DERR; printk(KERN_WARNING "%s: decrypt error, wrong cipher/key?\n", c->dev->name); } return TW_ERROR; } /* c->flags|=CIPF_NOTIFY_DERR; */ p=*(buf+(*len)-5); (*len)-=((p>>4)&7)+5; cipe_checkrkey(c);#define CTLBITS 0x06 dprintk(DEB_CRYPT, (KERN_INFO "%s: decrypt len=%d pad=%d typ=%02X\n", c->dev->name, (*len), (p>>4)&7, p&CTLBITS)); return (p&CTLBITS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -