1 /*********************************************************************** 2 ** 3 ** Debug output functions for Skein hashing. 4 ** 5 ** Source code author: Doug Whiting, 2008. 6 ** 7 ** This algorithm and source code is released to the public domain. 8 ** 9 ************************************************************************/ 10 #include <stdio.h> 11 12 #ifdef SKEIN_DEBUG /* only instantiate this code if SKEIN_DEBUG is on */ 13 #include "skein.h" 14 15 static const char INDENT[] = " "; /* how much to indent on new line */ 16 17 uint_t skein_DebugFlag = 0; /* off by default. Must be set externally */ 18 19 static void Show64_step(size_t cnt,const u64b_t *X,size_t step) 20 { 21 size_t i,j; 22 for (i=j=0;i < cnt;i++,j+=step) 23 { 24 if (i % 4 == 0) printf(INDENT); 25 printf(" %08X.%08X ",(uint_32t)(X[j] >> 32),(uint_32t)X[j]); 26 if (i % 4 == 3 || i==cnt-1) printf("\n"); 27 fflush(stdout); 28 } 29 } 30 31 #define Show64(cnt,X) Show64_step(cnt,X,1) 32 33 static void Show64_flag(size_t cnt,const u64b_t *X) 34 { 35 size_t xptr = (size_t) X; 36 size_t step = (xptr & 1) ? 2 : 1; 37 if (step != 1) 38 { 39 X = (const u64b_t *) (xptr & ~1); 40 } 41 Show64_step(cnt,X,step); 42 } 43 44 static void Show08(size_t cnt,const u08b_t *b) 45 { 46 size_t i; 47 for (i=0;i < cnt;i++) 48 { 49 if (i %16 == 0) printf(INDENT); 50 else if (i % 4 == 0) printf(" "); 51 printf(" %02X",b[i]); 52 if (i %16 == 15 || i==cnt-1) printf("\n"); 53 fflush(stdout); 54 } 55 } 56 57 static const char *AlgoHeader(uint_t bits) 58 { 59 if (skein_DebugFlag & SKEIN_DEBUG_THREEFISH) 60 switch (bits) 61 { 62 case 256: return ":Threefish-256: "; 63 case 512: return ":Threefish-512: "; 64 case 1024: return ":Threefish-1024:"; 65 } 66 else 67 switch (bits) 68 { 69 case 256: return ":Skein-256: "; 70 case 512: return ":Skein-512: "; 71 case 1024: return ":Skein-1024:"; 72 } 73 return NULL; 74 } 75 76 void Skein_Show_Final(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t cnt,const u08b_t *outPtr) 77 { 78 if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG)) 79 if (skein_DebugFlag & SKEIN_DEBUG_FINAL) 80 { 81 printf("\n%s Final output=\n",AlgoHeader(bits)); 82 Show08(cnt,outPtr); 83 printf(" ++++++++++\n"); 84 fflush(stdout); 85 } 86 } 87 88 /* show state after a round (or "pseudo-round") */ 89 void Skein_Show_Round(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t r,const u64b_t *X) 90 { 91 static uint_t injectNum=0; /* not multi-thread safe! */ 92 93 if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG)) 94 if (skein_DebugFlag) 95 { 96 if (r >= SKEIN_RND_SPECIAL) 97 { /* a key injection (or feedforward) point */ 98 injectNum = (r == SKEIN_RND_KEY_INITIAL) ? 0 : injectNum+1; 99 if ( skein_DebugFlag & SKEIN_DEBUG_INJECT || 100 ((skein_DebugFlag & SKEIN_DEBUG_FINAL) && r == SKEIN_RND_FEED_FWD)) 101 { 102 printf("\n%s",AlgoHeader(bits)); 103 switch (r) 104 { 105 case SKEIN_RND_KEY_INITIAL: 106 printf(" [state after initial key injection]"); 107 break; 108 case SKEIN_RND_KEY_INJECT: 109 printf(" [state after key injection #%02d]",injectNum); 110 break; 111 case SKEIN_RND_FEED_FWD: 112 printf(" [state after plaintext feedforward]"); 113 injectNum = 0; 114 break; 115 } 116 printf("=\n"); 117 Show64(bits/64,X); 118 if (r== SKEIN_RND_FEED_FWD) 119 printf(" ----------\n"); 120 } 121 } 122 else if (skein_DebugFlag & SKEIN_DEBUG_ROUNDS) 123 { 124 uint_t j; 125 u64b_t p[SKEIN_MAX_STATE_WORDS]; 126 const u08b_t *perm; 127 const static u08b_t PERM_256 [4][ 4] = { { 0,1,2,3 }, { 0,3,2,1 }, { 0,1,2,3 }, { 0,3,2,1 } }; 128 const static u08b_t PERM_512 [4][ 8] = { { 0,1,2,3,4,5,6,7 }, 129 { 2,1,4,7,6,5,0,3 }, 130 { 4,1,6,3,0,5,2,7 }, 131 { 6,1,0,7,2,5,4,3 } 132 }; 133 const static u08b_t PERM_1024[4][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 }, 134 { 0, 9, 2,13, 6,11, 4,15,10, 7,12, 3,14, 5, 8, 1 }, 135 { 0, 7, 2, 5, 4, 3, 6, 1,12,15,14,13, 8,11,10, 9 }, 136 { 0,15, 2,11, 6,13, 4, 9,14, 1, 8, 5,10, 3,12, 7 } 137 }; 138 139 if ((skein_DebugFlag & SKEIN_DEBUG_PERMUTE) && (r & 3)) 140 { 141 printf("\n%s [state after round %2d (permuted)]=\n",AlgoHeader(bits),(int)r); 142 switch (bits) 143 { 144 case 256: perm = PERM_256 [r&3]; break; 145 case 512: perm = PERM_512 [r&3]; break; 146 default: perm = PERM_1024[r&3]; break; 147 } 148 for (j=0;j<bits/64;j++) 149 p[j] = X[perm[j]]; 150 Show64(bits/64,p); 151 } 152 else 153 { 154 printf("\n%s [state after round %2d]=\n",AlgoHeader(bits),(int)r); 155 Show64(bits/64,X); 156 } 157 } 158 } 159 } 160 161 /* show state after a round (or "pseudo-round"), given a list of pointers */ 162 void Skein_Show_R_Ptr(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t r,const u64b_t *X_ptr[]) 163 { 164 uint_t i; 165 u64b_t X[SKEIN_MAX_STATE_WORDS]; 166 167 for (i=0;i<bits/64;i++) /* copy over the words */ 168 X[i] = X_ptr[i][0]; 169 Skein_Show_Round(bits,h,r,X); 170 } 171 172 173 /* show the state at the start of a block */ 174 void Skein_Show_Block(uint_t bits,const Skein_Ctxt_Hdr_t *h,const u64b_t *X,const u08b_t *blkPtr, 175 const u64b_t *wPtr, const u64b_t *ksPtr, const u64b_t *tsPtr) 176 { 177 uint_t n; 178 if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG)) 179 if (skein_DebugFlag) 180 { 181 if (skein_DebugFlag & SKEIN_DEBUG_HDR) 182 { 183 printf("\n%s Block: outBits=%4d. T0=%06X.",AlgoHeader(bits),(uint_t) h->hashBitLen,(uint_t)h->T[0]); 184 printf(" Type="); 185 n = (uint_t) ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) >> SKEIN_T1_POS_BLK_TYPE); 186 switch (n) 187 { 188 case SKEIN_BLK_TYPE_KEY: printf("KEY. "); break; 189 case SKEIN_BLK_TYPE_CFG: printf("CFG. "); break; 190 case SKEIN_BLK_TYPE_PERS: printf("PERS."); break; 191 case SKEIN_BLK_TYPE_PK : printf("PK. "); break; 192 case SKEIN_BLK_TYPE_KDF: printf("KDF. "); break; 193 case SKEIN_BLK_TYPE_MSG: printf("MSG. "); break; 194 case SKEIN_BLK_TYPE_OUT: printf("OUT. "); break; 195 default: printf("0x%02X.",n); break; 196 } 197 printf(" Flags="); 198 printf((h->T[1] & SKEIN_T1_FLAG_FIRST) ? " First":" "); 199 printf((h->T[1] & SKEIN_T1_FLAG_FINAL) ? " Final":" "); 200 printf((h->T[1] & SKEIN_T1_FLAG_BIT_PAD) ? " Pad" :" "); 201 n = (uint_t) ((h->T[1] & SKEIN_T1_TREE_LVL_MASK) >> SKEIN_T1_POS_TREE_LVL); 202 if (n) 203 printf(" TreeLevel = %02X",n); 204 printf("\n"); 205 fflush(stdout); 206 } 207 if (skein_DebugFlag & SKEIN_DEBUG_TWEAK) 208 { 209 printf(" Tweak:\n"); 210 Show64(2,h->T); 211 } 212 if (skein_DebugFlag & SKEIN_DEBUG_STATE) 213 { 214 printf(" %s words:\n",(skein_DebugFlag & SKEIN_DEBUG_THREEFISH)?"Key":"State"); 215 Show64(bits/64,X); 216 } 217 if (skein_DebugFlag & SKEIN_DEBUG_KEYSCHED) 218 { 219 printf(" Tweak schedule:\n"); 220 Show64_flag(3,tsPtr); 221 printf(" Key schedule:\n"); 222 Show64_flag((bits/64)+1,ksPtr); 223 } 224 if (skein_DebugFlag & SKEIN_DEBUG_INPUT_64) 225 { 226 printf(" Input block (words):\n"); 227 Show64(bits/64,wPtr); 228 } 229 if (skein_DebugFlag & SKEIN_DEBUG_INPUT_08) 230 { 231 printf(" Input block (bytes):\n"); 232 Show08(bits/8,blkPtr); 233 } 234 } 235 } 236 237 void Skein_Show_Key(uint_t bits,const Skein_Ctxt_Hdr_t *h,const u08b_t *key,size_t keyBytes) 238 { 239 if (keyBytes) 240 if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG)) 241 if (skein_DebugFlag & SKEIN_DEBUG_KEY) 242 { 243 printf("\n%s MAC key = %4u bytes\n",AlgoHeader(bits),(unsigned) keyBytes); 244 Show08(keyBytes,key); 245 } 246 } 247 #endif 248