cast6.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * File: cast6.c
  3. * Author: Daniel Otte
  4. * Date: 09.09.2006
  5. * License: GPL
  6. * Description: Implementation of the CAST6 (aka CAST-256) cipher algorithm as described in RFC 2612
  7. *
  8. */
  9. #include <stdint.h>
  10. #include <string.h>
  11. #include <crypto/cast6.h>
  12. #include <crypto/cast6_sboxes.h>
  13. #define CHANGE_ENDIAN32(x) (((x)<<24 | (x)>>24 | ((x)&0xff00)<<8 | ((x)&0xff0000)>>8)&0xffffffff)
  14. static
  15. uint8_t kr(uint8_t i, const cast6_ctx_t* ctx){
  16. uint8_t ret;
  17. ret = ctx->krx[i/2];
  18. if(i&1){
  19. ret >>= 4;
  20. }else{
  21. ret &= 0x0f;
  22. }
  23. /* now get the high bit */
  24. ret |= ((ctx->krx[24+i/8])&(1<<(i%8)))?0x10:0x00;
  25. return ret;
  26. }
  27. static
  28. void set_kr(uint8_t value, uint8_t i, cast6_ctx_t* ctx){
  29. value &= 0x1F;
  30. (ctx->krx[i/2]) &= 0xF0>>((i&1)*4); /* clear the location where v should go */
  31. (ctx->krx[i/2]) |= (value&0x0f)<<((i&1)*4);
  32. /* now set the high bit */
  33. (ctx->krx[24+i/8]) &= ~(1<<(i%8)); /* clear the location where v should go */
  34. (ctx->krx[24+i/8]) |= (value>>4)<<(i%8);
  35. }
  36. #define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
  37. #define ROTR32(a,n) (((a)>>(n))|((a)<<(32-(n))))
  38. #define S1(a) (s1[(a)])
  39. #define S2(a) (s2[(a)])
  40. #define S3(a) (s3[(a)])
  41. #define S4(a) (s4[(a)])
  42. #define A ((uint8_t)(v>>(8*3)))
  43. #define B ((uint8_t)(v>>(8*2)))
  44. #define C ((uint8_t)(v>>(8*1)))
  45. #define D ((uint8_t)(v>>(8*0)))
  46. static
  47. uint32_t f1(uint32_t v, uint8_t kri, uint32_t kmi){
  48. uint32_t o;
  49. kri &= 0x1F;
  50. v = ROTL32(kmi+v, kri);
  51. o = S1(A);
  52. o ^= S2(B);
  53. o -= S3(C);
  54. o += S4(D);
  55. return o;
  56. }
  57. static
  58. uint32_t f2(uint32_t v, uint8_t kri, uint32_t kmi){
  59. uint32_t o;
  60. kri &= 0x1F;
  61. v = ROTL32(kmi^v, kri);
  62. o = S1(A);
  63. o -= S2(B);
  64. o += S3(C);
  65. o ^= S4(D);
  66. return o;
  67. }
  68. static
  69. uint32_t f3(uint32_t v, uint8_t kri, uint32_t kmi){
  70. uint32_t o;
  71. kri &= 0x1F;
  72. v = ROTL32(kmi-v, kri);
  73. o = S1(A);
  74. o += S2(B);
  75. o ^= S3(C);
  76. o -= S4(D);
  77. return o;
  78. }
  79. #undef A
  80. #undef B
  81. #undef C
  82. #undef D
  83. #define A (((uint32_t*)buffer)[0])
  84. #define B (((uint32_t*)buffer)[1])
  85. #define C (((uint32_t*)buffer)[2])
  86. #define D (((uint32_t*)buffer)[3])
  87. static
  88. void q(void* buffer, uint8_t i, const cast6_ctx_t* ctx){
  89. C ^= f1(D, kr(i*4+0, ctx), ctx->km[i][0]);
  90. B ^= f2(C, kr(i*4+1, ctx), ctx->km[i][1]);
  91. A ^= f3(B, kr(i*4+2, ctx), ctx->km[i][2]);
  92. D ^= f1(A, kr(i*4+3, ctx), ctx->km[i][3]);
  93. }
  94. static
  95. void qbar(void* buffer, uint8_t i, const cast6_ctx_t* ctx){
  96. D ^= f1(A, kr(i*4+3, ctx), ctx->km[i][3]);
  97. A ^= f3(B, kr(i*4+2, ctx), ctx->km[i][2]);
  98. B ^= f2(C, kr(i*4+1, ctx), ctx->km[i][1]);
  99. C ^= f1(D, kr(i*4+0, ctx), ctx->km[i][0]);
  100. }
  101. void cast6_enc(void* buffer, const cast6_ctx_t* ctx){
  102. uint8_t i;
  103. for(i=0; i<32/4; ++i){
  104. ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
  105. }
  106. for(i=0; i<6; ++i){
  107. q(buffer, i, ctx);
  108. }
  109. for(i=6; i<12; ++i){
  110. qbar(buffer, i, ctx);
  111. }
  112. for(i=0; i<32/4; ++i){
  113. ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
  114. }
  115. }
  116. void cast6_dec(void* buffer, const cast6_ctx_t* ctx){
  117. uint8_t i;
  118. for(i=0; i<32/4; ++i){
  119. ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
  120. }
  121. for(i=12; i>6; --i){
  122. q(buffer, i-1, ctx);
  123. }
  124. for(i=6; i>0; --i){
  125. qbar(buffer, i-1, ctx);
  126. }
  127. for(i=0; i<32/4; ++i){
  128. ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
  129. }
  130. }
  131. #undef A
  132. #undef B
  133. #undef C
  134. #undef D
  135. #define A (((uint32_t*)buffer)[0])
  136. #define B (((uint32_t*)buffer)[1])
  137. #define C (((uint32_t*)buffer)[2])
  138. #define D (((uint32_t*)buffer)[3])
  139. #define E (((uint32_t*)buffer)[4])
  140. #define F (((uint32_t*)buffer)[5])
  141. #define G (((uint32_t*)buffer)[6])
  142. #define H (((uint32_t*)buffer)[7])
  143. /*
  144. * we might later make it optional to use this small thing
  145. static
  146. void w(void* buffer, uint8_t* tr, uint32_t* tm){
  147. G ^= f1(H, (tr[0]&0x0f)+(tr[5]&0x01)?0x10:0x00, tm[0]);
  148. F ^= f2(G, (tr[0]>>4) +(tr[5]&0x02)?0x10:0x00, tm[1]);
  149. E ^= f3(F, (tr[1]&0x0f)+(tr[5]&0x04)?0x10:0x00, tm[2]);
  150. D ^= f1(E, (tr[1]>>4) +(tr[5]&0x08)?0x10:0x00, tm[3]);
  151. C ^= f2(D, (tr[2]&0x0f)+(tr[5]&0x10)?0x10:0x00, tm[4]);
  152. B ^= f3(C, (tr[2]>>4) +(tr[5]&0x20)?0x10:0x00, tm[5]);
  153. A ^= f1(B, (tr[3]&0x0f)+(tr[5]&0x40)?0x10:0x00, tm[6]);
  154. H ^= f2(A, (tr[3]>>4) +(tr[5]&0x80)?0x10:0x00, tm[7]);
  155. }
  156. */
  157. static
  158. void w(void* buffer, uint8_t* tr, uint32_t* tm){
  159. G ^= f1(H, tr[0], tm[0]);
  160. F ^= f2(G, tr[1], tm[1]);
  161. E ^= f3(F, tr[2], tm[2]);
  162. D ^= f1(E, tr[3], tm[3]);
  163. C ^= f2(D, tr[4], tm[4]);
  164. B ^= f3(C, tr[5], tm[5]);
  165. A ^= f1(B, tr[6], tm[6]);
  166. H ^= f2(A, tr[7], tm[7]);
  167. }
  168. /*
  169. void dump_ctx(const cast6_ctx_t* ctx){
  170. uint8_t i,t;
  171. cli_putstr("\r\n DBG:");
  172. for(i=0; i<12; ++i){
  173. cli_putstr("\r\n DBG:");
  174. cli_putstr(" rotk1=");
  175. t=kr(i*4+0, ctx);
  176. cli_hexdump(&t,1);
  177. cli_putstr(" rotk2=");
  178. t=kr(i*4+1, ctx);
  179. cli_hexdump(&t,1);
  180. cli_putstr(" rotk3=");
  181. t=kr(i*4+2, ctx);
  182. cli_hexdump(&t,1);
  183. cli_putstr(" rotk4=");
  184. t=kr(i*4+3, ctx);
  185. cli_hexdump(&t,1);
  186. cli_putstr("\r\n ");
  187. cli_putstr(" mask1=");
  188. cli_hexdump(&(ctx->km[i][0]),4);
  189. cli_putstr(" mask2=");
  190. cli_hexdump(&(ctx->km[i][1]),4);
  191. cli_putstr(" mask3=");
  192. cli_hexdump(&(ctx->km[i][2]),4);
  193. cli_putstr(" mask4=");
  194. cli_hexdump(&(ctx->km[i][3]),4);
  195. cli_putstr("\r\n;-----");
  196. }
  197. }
  198. */
  199. #define CR 19
  200. #define CM 0x5A827999
  201. #define MR 17
  202. #define MM 0x6ED9EBA1
  203. void cast6_init(const void* key, uint16_t keysize_b, cast6_ctx_t* ctx){
  204. uint8_t buffer[32];
  205. uint8_t cr=CR, tr[8];
  206. uint32_t cm=CM, tm[8];
  207. uint8_t i,j;
  208. memset(buffer, 0, 32);
  209. memcpy(buffer, key, (keysize_b+7)/8);
  210. for(i=0; i<32/4; ++i){
  211. ((uint32_t*)buffer)[i] = CHANGE_ENDIAN32(((uint32_t*)buffer)[i]);
  212. }
  213. for(i=0; i<24; ++i){
  214. for(j=0; j<8; ++j){
  215. tm[j] = cm;
  216. cm += MM;
  217. tr[j] = cr&0x1F;
  218. cr += MR;
  219. }
  220. w(buffer, tr, tm);
  221. if(i&1){
  222. j=i/2;
  223. ctx->km[j][0]=H;
  224. ctx->km[j][1]=F;
  225. ctx->km[j][2]=D;
  226. ctx->km[j][3]=B;
  227. set_kr(buffer[0 * 4],j*4+0,ctx);
  228. set_kr(buffer[2 * 4],j*4+1,ctx);
  229. set_kr(buffer[4 * 4],j*4+2,ctx);
  230. set_kr(buffer[6 * 4],j*4+3,ctx);
  231. }
  232. }
  233. }