2014-10-12 13:59 GMT+02:00 supraja reddy <supraja0...@gmail.com>: > Hello , > > I , Supraja , am interested to work with ffmpeg as a part of OPW internship > . As a part of the qualification task , I have taken up the implementation > of Cast 128 algorithm implementation . I have written the code for the same > and have attached the patch of the same with this mail . It is currently > written for ecb mode . It takes keysizes of 40 , 80 and 128 bits for now . > > Please let me know if there are any further changes or suggestions .
Hello, thanks for your patch! Please make sure to run tools/patcheck as Michael suggested and fix the reported problems. Some preliminary comments below, hopefully I'll have more time to test/review the patch in the following days. > From b7aab16b09db2a3ca16144221f1516f7fec8a7a2 Mon Sep 17 00:00:00 2001 > From: Myra <supraja0...@gmail.com> Make sure your name and email address are configured correctly in git. > Date: Sun, 12 Oct 2014 11:39:24 +0530 > Subject: [PATCH] Added cast128 algorithm for ecb mode > > Signed-off-by: Myra <supraja0...@gmail.com> > --- > libavutil/Makefile | 3 + > libavutil/cast5.c | 521 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > libavutil/cast5.h | 37 ++++ > 3 files changed, 561 insertions(+) > create mode 100644 libavutil/cast5.c > create mode 100644 libavutil/cast5.h > > diff --git a/libavutil/Makefile b/libavutil/Makefile > index 65c6b53..22d345e 100644 > --- a/libavutil/Makefile > +++ b/libavutil/Makefile > @@ -15,6 +15,7 @@ HEADERS = adler32.h > \ > bprint.h \ > bswap.h \ > buffer.h \ > + cast5.c \ > channel_layout.h \ > common.h \ > cpu.h \ > @@ -82,6 +83,7 @@ OBJS = adler32.o > \ > blowfish.o \ > bprint.o \ > buffer.o \ > + cast5.o \ You need to add one more space after cast5.o to align the '\'. > channel_layout.o \ > cpu.o \ > crc.o \ > @@ -151,6 +153,7 @@ TESTPROGS = adler32 > \ > base64 \ > blowfish \ > bprint \ > + cast5 \ Same here, one more space is needed. > cpu \ > crc \ > des \ > diff --git a/libavutil/cast5.c b/libavutil/cast5.c > new file mode 100644 > index 0000000..ca7200c > --- /dev/null > +++ b/libavutil/cast5.c > @@ -0,0 +1,521 @@ > +#include "cast5.h" > +#include "common.h" > +#include "intreadwrite.h" > +#include "timer.h" I don't think we need timer.h > +/* > + * An implementation of the CAST128 algorithm Maybe add a note mentioning the RFC2144. > + * Copyright (c) 2014 Supraja Meedinti > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg 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 > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#define IA(x) ((x>>24) & 0xff) > +#define IB(x) ((x>>16) & 0xff) > +#define IC(x) ((x>>8) & 0xff) > +#define ID(x) (x & 0xff) I'd also suggest to add a macro for circular left shift (left rotation) and use it throughout the code: #define LR(x, c) ((x) << (c) | (x) >> (32 - (c))) > + > +typedef struct AVCAST5 { > + uint32_t Km[17]; > + uint32_t Kr[17]; > + int rounds; > +} AVCAST5; > + > + > + > +static uint32_t func(uint32_t D, uint32_t Km, uint32_t Kr, int rnum) > +{ > + uint32_t I,t,val; > + switch(rnum%3){ > + case 0: > + t=(Km-D); > + I=(t<<Kr)|(t>>(32-Kr)); > + val=((S1[IA(I)]+S2[IB(I)])^S3[IC(I)])-S4[ID(I)]; > + break; You can probably eliminate t, something like: I = LR(Km - D, Kr); > + case 1: > + t=Km+D; > + I=(t<<Kr)|(t>>(32-Kr)); > + val=((S1[IA(I)]^S2[IB(I)])-S3[IC(I)])+S4[ID(I)]; > + break; > + case 2: > + t=(Km^D); > + I=(t<<Kr)|(t>>(32-Kr)); > + val=((S1[IA(I)]-S2[IB(I)])+S3[IC(I)])^S4[ID(I)]; > + break; > + } > + return val; > +} > + > +static void GenerateRoundKeys(int rnds,uint32_t* K, uint32_t* q, uint32_t* p) We could call q->x and p->z to use the same names used in the RFC, and define: static void generate_round_keys(int rounds, uint32_t *K, uint32_t x[4], uint32_t z[4]) > +{ > + > p[0]=q[0]^S5[IB(q[3])]^S6[ID(q[3])]^S7[IA(q[3])]^S8[IC(q[3])]^S7[IA(q[2])]; > + > p[1]=q[2]^S5[IA(p[0])]^S6[IC(p[0])]^S7[IB(p[0])]^S8[ID(p[0])]^S8[IC(q[2])]; > + > p[2]=q[3]^S5[ID(p[1])]^S6[IC(p[1])]^S7[IB(p[1])]^S8[IA(p[1])]^S5[IB(q[2])]; > + > p[3]=q[1]^S5[IC(p[2])]^S6[IB(p[2])]^S7[ID(p[2])]^S8[IA(p[2])]^S6[ID(q[2])]; The block above computes p[] from (p[],q[]) and will be repeated later, it could be defined as a macro. > + > + K[1]=S5[IA(p[2])]^S6[IB(p[2])]^S7[ID(p[1])]^S8[IC(p[1])]^S5[IC(p[0])]; > + K[2]=S5[IC(p[2])]^S6[ID(p[2])]^S7[IB(p[1])]^S8[IA(p[1])]^S6[IC(p[1])]; > + K[3]=S5[IA(p[3])]^S6[IB(p[3])]^S7[ID(p[0])]^S8[IC(p[0])]^S7[IB(p[2])]; > + K[4]=S5[IC(p[3])]^S6[ID(p[3])]^S7[IB(p[0])]^S8[IA(p[0])]^S8[IA(p[3])]; > + > + > q[0]=p[2]^S5[IB(p[1])]^S6[ID(p[1])]^S7[IA(p[1])]^S8[IC(p[1])]^S7[IA(p[0])]; > + > q[1]=p[0]^S5[IA(q[0])]^S6[IC(q[0])]^S7[IB(q[0])]^S8[ID(q[0])]^S8[IC(p[0])]; > + > q[2]=p[1]^S5[ID(q[1])]^S6[IC(q[1])]^S7[IB(q[1])]^S8[IA(q[1])]^S5[IB(p[0])]; > + > q[3]=p[3]^S5[IC(q[2])]^S6[IB(q[2])]^S7[ID(q[2])]^S8[IA(q[2])]^S6[ID(p[0])]; Same here, the block above computes q[] from (p[],q[]) and will be repeated later, you could define a macro. > + > + K[5]=S5[ID(q[0])]^S6[IC(q[0])]^S7[IA(q[3])]^S8[IB(q[3])]^S5[IA(q[2])]; > + K[6]=S5[IB(q[0])]^S6[IA(q[0])]^S7[IC(q[3])]^S8[ID(q[3])]^S6[IB(q[3])]; > + K[7]=S5[ID(q[1])]^S6[IC(q[1])]^S7[IA(q[2])]^S8[IB(q[2])]^S7[ID(q[0])]; > + K[8]=S5[IB(q[1])]^S6[IA(q[1])]^S7[IC(q[2])]^S8[ID(q[2])]^S8[ID(q[1])]; > + > + > p[0]=q[0]^S5[IB(q[3])]^S6[ID(q[3])]^S7[IA(q[3])]^S8[IC(q[3])]^S7[IA(q[2])]; > + > p[1]=q[2]^S5[IA(p[0])]^S6[IC(p[0])]^S7[IB(p[0])]^S8[ID(p[0])]^S8[IC(q[2])]; > + > p[2]=q[3]^S5[ID(p[1])]^S6[IC(p[1])]^S7[IB(p[1])]^S8[IA(p[1])]^S5[IB(q[2])]; > + > p[3]=q[1]^S5[IC(p[2])]^S6[IB(p[2])]^S7[ID(p[2])]^S8[IA(p[2])]^S6[ID(q[2])]; > + > + K[9]=S5[ID(p[0])]^S6[IC(p[0])]^S7[IA(p[3])]^S8[IB(p[3])]^S5[IB(p[2])]; > + K[10]=S5[IB(p[0])]^S6[IA(p[0])]^S7[IC(p[3])]^S8[ID(p[3])]^S6[IA(p[3])]; > + K[11]=S5[ID(p[1])]^S6[IC(p[1])]^S7[IA(p[2])]^S8[IB(p[2])]^S7[IC(p[0])]; > + K[12]=S5[IB(p[1])]^S6[IA(p[1])]^S7[IC(p[2])]^S8[ID(p[2])]^S8[IC(p[1])]; > + > + > q[0]=p[2]^S5[IB(p[1])]^S6[ID(p[1])]^S7[IA(p[1])]^S8[IC(p[1])]^S7[IA(p[0])]; > + > q[1]=p[0]^S5[IA(q[0])]^S6[IC(q[0])]^S7[IB(q[0])]^S8[ID(q[0])]^S8[IC(p[0])]; > + > q[2]=p[1]^S5[ID(q[1])]^S6[IC(q[1])]^S7[IB(q[1])]^S8[IA(q[1])]^S5[IB(p[0])]; > + > q[3]=p[3]^S5[IC(q[2])]^S6[IB(q[2])]^S7[ID(q[2])]^S8[IA(q[2])]^S6[ID(p[0])]; > + > + if(rnds==16) { > + > K[13]=S5[IA(q[2])]^S6[IB(q[2])]^S7[ID(q[1])]^S8[IC(q[1])]^S5[ID(q[0])]; > + > K[14]=S5[IC(q[2])]^S6[ID(q[2])]^S7[IB(q[1])]^S8[IA(q[1])]^S6[ID(q[1])]; > + > K[15]=S5[IA(q[3])]^S6[IB(q[3])]^S7[ID(q[0])]^S8[IC(q[0])]^S7[IA(q[2])]; > + > K[16]=S5[IC(q[3])]^S6[ID(q[3])]^S7[IB(q[0])]^S8[IA(q[0])]^S8[IB(q[3])]; > + } > +} > + > +int av_cast5_init(AVCAST5* cs, const uint8_t *key, int key_bits) > +{ > + uint8_t newKey[16]; > + int i; > + uint32_t p[4],q[4]; We need: memset(newKey, 0, sizeof(newKey)); > + if(key_bits%8!=0||key_bits<40||key_bits>128) if (key_bits % 8 || key_bits < 40 || key_bits > 128) > + return -1; > + memcpy(newKey,key,16*sizeof(key[0])); memcpy(newKey, key, key_bits / 8); > + if (key_bits!=128) { > + for(i=15;i>=key_bits/8;i--) > + newKey[i]=0x00; > + } This if() is not needed anymore, since we used memset() on newKey. > + if(key_bits==128){ > + cs->rounds=16; > + } else { > + cs->rounds=12; > + } cs->rounds = key_bits <= 80 ? 12 : 16; > + for(i=0;i<4;i++) > + q[i]=AV_RB32(newKey+(4*i)); > + GenerateRoundKeys(cs->rounds,cs->Km,q,p); > + GenerateRoundKeys(cs->rounds,cs->Kr,q,p); > + for(i=0;i<cs->rounds;i++) > + cs->Kr[i]=cs->Kr[i]&0x1f; > + return 0; > +} > + > +static void encipher(AVCAST5* cs,uint8_t* dst,const uint8_t* src) > +{ > + int i; > + uint32_t temp,sdst[2]; > + sdst[0]=AV_RB32(src); > + sdst[1]=AV_RB32(src+4); > + for(i=1;i<=cs->rounds;i++){ > + temp=sdst[1]; > + sdst[1]=sdst[0]^(func(sdst[1],cs->Km[i],cs->Kr[i],i)); > + sdst[0]=temp; > + } > + AV_WB32(dst,sdst[1]); > + AV_WB32(dst+4,sdst[0]); > +} > + > +static void decipher(AVCAST5* cs,uint8_t* dst,const uint8_t* src) > +{ > + int i; > + uint32_t temp,sdst[2]; > + sdst[0]=AV_RB32(src); > + sdst[1]=AV_RB32(src+4); > + for(i=cs->rounds;i>0;i--){ > + temp=sdst[1]; > + sdst[1]=sdst[0]^(func(sdst[1],cs->Km[i],cs->Kr[i],i)); > + sdst[0]=temp; > + } > + AV_WB32(dst,sdst[1]); > + AV_WB32(dst+4,sdst[0]); > +} > + > +void av_cast5_crypt(AVCAST5* cs, uint8_t* dst, const uint8_t* src, int > count, int decrypt) > +{ > + while(count--) > + { > + if(decrypt){ > + decipher(cs,dst,src); > + } else { > + encipher(cs,dst,src); > + } > + src=src+8; > + dst=dst+8; > + } > +} > + > +#include<stdio.h> > +#include<stdlib.h> > +#include"log.h" > +#include"lfg.h" Not sure we need lfg.h? > + > +#ifdef TEST > +int main(int argc, char** argv) > +{ > + AVCAST5 cs; > + uint8_t > Key[3][16]={{0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9a}, > + {0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45}, > + {0x01,0x23,0x45,0x67,0x12}}; > + uint8_t rpt[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; > + uint8_t rct[3][8]={{0x23,0x8b,0x4f,0xe5,0x84,0x7e,0x44,0xb2}, > + {0xeb,0x6a,0x71,0x1a,0x2c,0x02,0x27,0x1b}, > + {0x7a,0xc8,0x16,0xd1,0x6e,0x9b,0x30,0x2e}}; > + int i,err=0; > + uint8_t temp[8]; > + av_log_set_level(AV_LOG_DEBUG); > + av_cast5_init(&cs,Key[0],128); > + av_cast5_crypt(&cs,temp,rpt,1,0); > + for(i=0;i<8;i++){ > + if(rct[0][i]!=temp[i]){ > + av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rct[0][i],temp[i]); > + err=1; > + } > + } > + av_cast5_crypt(&cs,temp,rct[0],1,1); > + for(i=0;i<8;i++){ > + if(rpt[i]!=temp[i]){ > + av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rpt[i],temp[i]); > + err=1; > + } > + } > + av_cast5_init(&cs,Key[1],80); > + av_cast5_crypt(&cs,temp,rpt,1,0); > + for(i=0;i<8;i++){ > + if(rct[1][i]!=temp[i]){ > + av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rct[1][i],temp[i]); > + err=1; > + } > + } > + av_cast5_crypt(&cs,temp,rct[1],1,1); > + for(i=0;i<8;i++){ > + if(rpt[i]!=temp[i]){ > + av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rpt[i],temp[i]); > + err=1; > + } > + } > + av_cast5_init(&cs,Key[2],40); > + av_cast5_crypt(&cs,temp,rpt,1,0); > + for(i=0;i<8;i++){ > + if(rct[2][i]!=temp[i]){ > + av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rct[2][i],temp[i]); > + err=1; > + } > + } > + av_cast5_crypt(&cs,temp,rct[2],1,1); > + for(i=0;i<8;i++){ > + if(rpt[i]!=temp[i]){ > + av_log(NULL,AV_LOG_ERROR,"%d %02x %02x\n",i,rpt[i],temp[i]); > + err=1; > + } > + } > + return err; > +} > + > +#endif > + > + > + > + > + > + > diff --git a/libavutil/cast5.h b/libavutil/cast5.h > new file mode 100644 > index 0000000..d2196b9 > --- /dev/null > +++ b/libavutil/cast5.h > @@ -0,0 +1,37 @@ > +/* > + * An implementation of the CAST128 algorithm > + * Copyright (c) 2014 Supraja Meedinti > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg 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 > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#ifndef AVUTIL_CAST5_H > +#define AVUTIL_CAST5_H > + > +#include <stdint.h> > + > +#include "attributes.h" > +#include "version.h" > + > +struct AVCAST5; > + > +int av_cast5_init(struct AVCAST5 *a, const uint8_t *key, int key_bits); > + > +void av_cast5_crypt(struct AVCAST5 *a, uint8_t *dst, const uint8_t *src, int > count,int decrypt); > + > + > +#endif > -- > 1.8.3.2 > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel