/***************************************************************************
*
Copyright 2013 CertiVox UK Ltd. *
*
This file is part of CertiVox MIRACL Crypto SDK. *
*
The CertiVox MIRACL Crypto SDK provides developers with an *
extensive and efficient set of cryptographic functions. *
For further information about its features and functionalities please *
refer to http://www.certivox.com *
*
* The CertiVox MIRACL Crypto SDK is free software: you can *
redistribute it and/or modify it under the terms of the *
GNU Affero General Public License as published by the *
Free Software Foundation, either version 3 of the License, *
or (at your option) any later version. *
*
* The CertiVox MIRACL Crypto SDK is distributed in the hope *
that it will be useful, but WITHOUT ANY WARRANTY; without even the *
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
See the GNU Affero General Public License for more details. *
*
* You should have received a copy of the GNU Affero General Public *
License along with CertiVox MIRACL Crypto SDK. *
If not, see . *
*
You can be released from the requirements of the license by purchasing *
a commercial license. Buying such a license is mandatory as soon as you *
develop commercial activities involving the CertiVox MIRACL Crypto SDK *
without disclosing the source code of your own applications, or shipping *
the CertiVox MIRACL Crypto SDK with a closed source product. *
*
***************************************************************************/
/*** Basic Octet string maintainance routines ***/
#include "octet.h"
/* Output an octet string (Debug Only) */
void OCTET_OUTPUT(octet *w)
{
int i;
unsigned char ch;
for (i=0;ilen;i++)
{
ch=w->val[i];
printf("%02x",ch);
}
printf("\n");
}
void OCTET_OUTPUT_STRING(octet *w)
{
int i;
unsigned char ch;
for (i=0;ilen;i++)
{
ch=w->val[i];
printf("%c",ch);
}
/* printf("\n"); */
}
/* Convert C string to octet format - truncates if no room */
void OCTET_JOIN_STRING(char *s,octet *y)
{
int i,j;
i=y->len;
j=0;
while (s[j]!=0 && imax)
{
y->val[i]=s[j];
y->len++;
i++; j++;
}
}
/* compare 2 octet strings.
* If x==y return TRUE, else return FALSE */
int OCTET_COMPARE(octet *x,octet *y)
{
int i;
if (x->len>y->len) return 0;
if (x->lenlen) return 0;
for (i=0;ilen;i++)
{
if (x->val[i]!=y->val[i]) return 0;
}
return 1;
}
/* Append binary string to octet - truncates if no room */
void OCTET_JOIN_BYTES(char *b,int len,octet *y)
{
int i,j;
i=y->len;
for (j=0;jmax;j++)
{
y->val[i]=b[j];
y->len++;
i++;
}
}
/* Concatenates two octet strings */
void OCTET_JOIN_OCTET(octet *x,octet *y)
{ /* y=y || x */
int i,j;
if (x==NULL) return;
for (i=0;ilen;i++)
{
j=y->len+i;
if (j>=y->max)
{
y->len=y->max;
return;
}
y->val[j]=x->val[i];
}
y->len+=x->len;
}
/* Append byte to octet rep times */
void OCTET_JOIN_BYTE(int ch,int rep,octet *y)
{
int i,j;
i=y->len;
for (j=0;jmax;j++)
{
y->val[i]=ch;
y->len++;
i++;
}
}
/* XOR common bytes of x with y */
void OCTET_XOR(octet *x,octet *y)
{ /* xor first x->len bytes of y */
int i;
for (i=0;ilen && ilen;i++)
{
y->val[i]^=x->val[i];
}
}
/* clear an octet */
void OCTET_EMPTY(octet *w)
{
w->len=0;
}
/* Kill an octet string - Zeroise it for security */
void OCTET_CLEAR(octet *w)
{
int i;
for (i=0;imax;i++) w->val[i]=0;
w->len=0;
}
/* OCTET_JOIN_LONG primitive */
/* appends long x of length len bytes to OCTET string */
void OCTET_JOIN_LONG(long x,int len,octet *y)
{
int i,j,n;
n=y->len+len;
if (n>y->max || len<=0) return;
for (i=y->len;ival[i]=0;
y->len=n;
i=y->len;
while (x>0 && i>0)
{
i--;
y->val[i]=x%256;
x/=256;
}
}
/* Pad an octet to a given length */
void OCTET_PAD(int n,octet *w)
{
int i,d;
if (w->len>=n || n>w->max) return;
d=n-w->len;
for (i=n-1;i>=d;i--)
w->val[i]=w->val[i-d];
for (i=d-1;i>=0;i--)
w->val[i]=0;
w->len=n;
}
/* Convert an octet string to base64 string */
void OCTET_TO_BASE64(octet *w,char *b)
{
int i,j,k,rem,last;
int c,ch[4];
unsigned char ptr[3];
rem=w->len%3; j=k=0; last=4;
while (jlen)
{
for (i=0;i<3;i++)
{
if (jlen) ptr[i]=w->val[j++];
else {ptr[i]=0; last--;}
}
ch[0]=(ptr[0]>>2)&0x3f;
ch[1]=((ptr[0]<<4)|(ptr[1]>>4))&0x3f;
ch[2]=((ptr[1]<<2)|(ptr[2]>>6))&0x3f;
ch[3]=ptr[2]&0x3f;
for (i=0;i=26 && c<52) c+=71;
if (c>=52 && c<62) c-=4;
if (c==62) c='+';
if (c==63) c='/';
b[k++]=c;
}
}
if (rem>0) for (i=rem;i<3;i++) b[k++]='=';
b[k]='\0'; // dangerous!
}
void OCTET_FROM_BASE64(char *b,octet *w)
{
int i,j,k,pads,len=strlen(b);
int c,ch[4],ptr[3];
int lead=1;
j=k=0;
while (jmax)
{
pads=0;
for (i=0;i<4;i++)
{
c=80+b[j++];
if (c<=112) continue; /* ignore white space */
if (c>144 && c<171) c-=145;
if (c>176 && c<203) c-=151;
if (c>127 && c<138) c-=76;
if (c==123) c=62;
if (c==127) c=63;
if (c==141) {pads++; continue;} /* ignore pads '=' */
ch[i]=c;
}
ptr[0]=(ch[0]<<2)|(ch[1]>>4);
ptr[1]=(ch[1]<<4)|(ch[2]>>2);
ptr[2]=(ch[2]<<6)|ch[3];
for (i=0;i<3-pads && kmax;i++)
{ /* don't put in leading zeros */
/* if (lead && ptr[i]==0) continue; */
w->val[k++]=ptr[i];
lead=0;
}
}
w->len=k;
}
/* copy an octet string - truncates if no room */
void OCTET_COPY(octet *x,octet *y)
{
int i;
OCTET_CLEAR(y);
y->len=x->len;
if (y->len>y->max) y->len=y->max;
for (i=0;ilen;i++)
y->val[i]=x->val[i];
}
/* XOR m with all of x */
void OCTET_XOR_BYTE(int m,octet *x)
{
int i;
for (i=0;ilen;i++) x->val[i]^=m;
}
/* truncates x to n bytes and places the rest in y (if y is not NULL) */
void OCTET_CHOP(octet *x,int n,octet *y)
{
int i;
if (n>=x->len)
{
if (y!=NULL) y->len=0;
return;
}
if (y!=NULL) y->len=x->len-n;
x->len=n;
if (y!=NULL)
{
for (i=0;ilen && imax;i++) y->val[i]=x->val[i+n];
}
}