home *** CD-ROM | disk | FTP | other *** search
- /*
- ** xpkSICR - SImple CRypt library
- ** example code for a DiskProtection compatible XPK sublibrary
- ** xor every longword with the password value
- **
- ** This code is based on various other XPK examples and modified 1996 by
- ** Patrick Ohly. It can be compiled with SAS/C. It may be used for your
- ** own libraries, as long as you mention DiskProtection and my name.
- ** You should clearly state that a DiskProtection compatible xpklibrary
- ** should not be used with XPK when distributing it!
- **
- ** DiskProtection compatible means:
- ** - a valid XPK sublibrary
- ** - stored in libs:compressors
- ** - XPKIF_NEEDPASSWD set
- ** - XPKIF_LOOSY not set
- ** - size of a chunk does not increase when encrypted
- **
- ** The last point is a problem with the XPK standard:
- ** xpkmaster.library expects sublibraries to save the mode
- ** with every encrypted/packed chunk and to be able to recognize
- ** wrong passwords, i.e. checksums are nescessary, too.
- ** Both is not possible with DiskProtection, because every diskblock
- ** has to be stored in place and there is no space for any extra byte.
- **
- ** However, you _can_ use different modes with DiskProtection:
- ** In contrast to the xpkmaster.library DiskProtection provides the
- ** correct mode on decryption, too. You also don't have to bother with checking
- ** the password. DiskProtection does this itself.
- */
-
- #include <proto/exec.h>
- #include <exec/memory.h>
- #include <limits.h>
-
- #include <libraries/xpksub.h>
-
- /*
- ** only one mode in this example
- ** speed is guessed
- */
- static struct XpkMode SicrMode =
- {
- NULL, 100, XPKMF_A3000SPEED, 0,0, 500,500, 0, USHRT_MAX/1024, "simple"
- };
-
- static struct XpkInfo SicrInfo = {
- 0, /* info version */
- 1, /* lib version */
- 0, /* master vers */
- 0, /* ModesVersion */
- "SICR", /* short name */
- "Simple Crypt 0.1", /* long name */
- "simply xor's every long word", /* description */
- (ULONG)'SICR', /* 4 letter ID */
- XPKIF_PK_CHUNK | /* flags */
- XPKIF_UP_CHUNK |
- XPKIF_ENCRYPTION|
- XPKIF_NEEDPASSWD,
- 0x40000000, /* 1GB */ /* max in chunk */
- 0, /* min in chunk */
- 32768, /* def in chunk */
- "Encrypting", /* pk message */
- "Decrypting", /* up message */
- "Encrypted", /* pk past msg */
- "Decrypted", /* up past msg */
- 0, /* def mode */
- 0, /* pad */
- &SicrMode /* modes */
- };
-
-
- /*
- ** Returns the info structure of our encryptor
- **/
- struct XpkInfo * __saveds __asm
- SicrXpksPackerInfo(void)
- {
- return &SicrInfo;
- }
-
-
- /*
- ** This forces the next chunk to be decryptable independent from the
- ** previous one. This is always the case in SICR.
- **/
- long __saveds __asm
- SicrXpksPackReset(register __a0 XPARAMS* xpar)
- {
- return XPKERR_OK;
- }
-
- /*
- ** help function:
- ** calculate value from password
- ** taken from FEAL (special thanks to Christian von Roques)
- */
-
- typedef unsigned char Word8;
- typedef unsigned short Word16;
- typedef unsigned long Word32;
- typedef struct { unsigned long lft, rgt; } Word64;
-
- static Word64 password (APTR *s)
- {
- Word8* p=(Word8*)s;
- Word64 x;
- Word32 t;
-
- x.lft = 0;
- x.rgt = 0;
-
- while (p && *p)
- {
- t = x.lft;
- x.lft = x.rgt;
- x.rgt = ((t << 9) | (t >> 23)) + (Word32) *p;
- p++;
- }
- return(x);
- }
-
-
- /*
- ** Encrypt a chunk
- **
- ** xpar->Sub[0-3] can be stored to save private data,
- ** e.g. pointers to allocated resources
- **
- ** This fields will be zero for the first chunk, so
- ** you can initialize encryption then, store your data
- ** there and set them to zero again when cleaning up.
- **
- ** One xpar block will never be used for both encryption
- ** and decryption without cleaning up before changing the
- ** mode of operation.
- **/
- long __saveds __asm
- SicrXpksPackChunk(register __a0 XPARAMS *xpar)
- {
- if(xpar->InLen <= xpar->OutBufLen)
- {
- ULONG *r = (ULONG*)xpar->InBuf,
- *w = (ULONG*)xpar->OutBuf,
- *e = (ULONG *)&(((UBYTE *)r)[xpar->InLen]);
- ULONG xor = xpar->Sub[0];
- Word64 x;
-
- if(!xor)
- {
- /* first hunk, calculate password */
- x = password(xpar->Password);
- xor = x.lft ^ x.rgt;
- /* should better not be zero :-) */
- if(!xor)
- xor = 0xFFFFFFFF;
- xpar->Sub[0] = xor;
- }
-
- /* encrypt */
- for(;r < e; r++, w++)
- *w = *r ^ xor;
-
- /* must be set! */
- xpar->OutLen = xpar->InLen;
- return XPKERR_OK;
- }
- else
- {
- /* error, should never occur with DiskProtection */
- xpar->OutLen = 0;
- return XPKERR_SMALLBUF;
- }
- }
-
- /*
- ** free all resource allocated in XircXpksPackChunk
- */
- void __saveds __asm
- SicrXpksPackFree(register __a0 XPARAMS* xpar)
- {
- /* xpar block could be used again with different password,
- ** thus this must be set to zero again
- */
- xpar->Sub[0] = NULL;
- }
-
- /*
- ** Decrypt a chunk
- **/
- long __saveds __asm
- SicrXpksUnpackChunk(register __a0 XPARAMS *xpar)
- {
- /* with SICR encryption is the same as decryption */
- return SicrXpksPackChunk(xpar);
- }
-
- /*
- ** free all resource allocated in XircXpksPackChunk
- */
- void __saveds __asm
- SicrXpksUnpackFree(register __a0 XPARAMS* xpar)
- {
- /* see above... */
- xpar->Sub[0] = NULL;
- }
-