/*************************************************************************** * 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]; } }