📄 loki97.c
字号:
if (cipher == NULL) return BAD_CIPHER_STATE; if (key == NULL) return BAD_KEY_INSTANCE; if (key->direction != DIR_ENCRYPT) return BAD_KEY_DIR; /* now call appropriate mode encrypt routine */ if (cipher->mode == MODE_ECB) return enECB(cipher, key, input, inputLen, outBuffer); else if (cipher->mode == MODE_CBC) return enCBC(cipher, key, input, inputLen, outBuffer); else if (cipher->mode == MODE_CFB1) return enCFB1(cipher, key, input, inputLen, outBuffer); else return BAD_CIPHER_MODE;}/* * encrypt blocks in ECB mode */static int enECB(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer){ int i,j,k; /* assorted loop counters */ int blocks = inputLen / (BLOCK_SIZE*8); /* compute # input blocks */ ULONG64 L, R; /* left and right data blocks */ ULONG64 nR, f_out; /* do some basic sanity checks on params */ if (inputLen % (BLOCK_SIZE*8) != 0) return BAD_CIPHER_INPUT; /* now loop over all blocks of input */ for (j = 0; j < blocks; j++) { /* pack input block into L and R */ L = byteToULONG64(input); input += 8; R = byteToULONG64(input); input += 8; if (debuglevel) fprintf(stderr,"%s: enECB(%08X%08X%08X%08X) ", NAME, L.l, L.r, R.l, R.r); if (debuglevel > 1) fprintf(stderr,"\n"); /* compute all rounds for this 1 block */ k = 0; for (i = 0; i < ROUNDS; i++) { nR = add64(R, key->SK[k++]); /* nR = R+SK(k) */ f_out = f(nR, key->SK[k++]); /* f = f(nR,SK(k+1)) */ nR = add64(nR, key->SK[k++]); /* nR = nR+SK(k+2) */ R.l = L.l ^ f_out.l; R.r = L.r ^ f_out.r; /* R = L XOR f */ L = nR; /* L = nR */ if (debuglevel > 1) fprintf(stderr," L[%02d]=%08X%08X; R[%02d]=%08X%08X; f(SK(%02d))=%08X%08X\n", i+1, L.l, L.r, i+1, R.l, R.r, k-2, f_out.l, f_out.r); } if (debuglevel > 0) fprintf(stderr,"= %08X%08X%08X%08X\n", R.l, R.r, L.l, L.r); /* unpack resulting L & R into output - undoing last swap */ ULONG64ToBYTE(outBuffer, R); outBuffer += 8; ULONG64ToBYTE(outBuffer, L); outBuffer += 8; } return TRUE;}/* * encrypt blocks in CBC mode */static int enCBC(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer){ int i,j,k; /* assorted loop counters */ int blocks = inputLen / (BLOCK_SIZE*8); /* compute # input blocks */ ULONG64 L, R; /* left and right data blocks */ ULONG64 nR, f_out; /* do some basic sanity checks on params */ if (inputLen % (BLOCK_SIZE*8) != 0) return BAD_CIPHER_INPUT; /* now loop over all blocks of input */ for (j = 0; j < blocks; j++) { /* pack input block into L and R */ L = byteToULONG64(input); input += 8; R = byteToULONG64(input); input += 8; /* XOR with IV value */ L.l ^= cipher->IVL.l; L.r ^= cipher->IVL.r; R.l ^= cipher->IVR.l; R.r ^= cipher->IVR.r; if (debuglevel) fprintf(stderr,"%s: enCBC(%08X%08X%08X%08X) ", NAME, L.l, L.r, R.l, R.r); if (debuglevel > 1) fprintf(stderr,"\n"); /* compute all rounds for this 1 block */ k = 0; for (i = 0; i < ROUNDS; i++) { nR = add64(R, key->SK[k++]); /* nR = R+SK(k) */ f_out = f(nR, key->SK[k++]); /* f = f(nR,SK(k+1)) */ nR = add64(nR, key->SK[k++]); /* nR = nR+SK(k+2) */ R.l = L.l ^ f_out.l; R.r = L.r ^ f_out.r; /* R = L XOR f */ L = nR; /* L = nR */ if (debuglevel > 1) fprintf(stderr," L[%02d]=%08X%08X; R[%02d]=%08X%08X; f(SK(%02d))=%08X%08X\n", i+1, L.l, L.r, i+1, R.l, R.r, k-2, f_out.l, f_out.r); } /* save new IV value (nb. undo last swap, as per output transform */ cipher->IVL = R; cipher->IVR = L; if (debuglevel > 0) fprintf(stderr,"= %08X%08X%08X%08X\n", R.l, R.r, L.l, L.r); /* unpack resulting L & R into output - undoing last swap */ ULONG64ToBYTE(outBuffer, R); outBuffer += 8; ULONG64ToBYTE(outBuffer, L); outBuffer += 8; } return TRUE;}/* * encrypt blocks in CFB1 mode */static int enCFB1(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer){ int i,j,k; /* assorted loop counters */ int b; /* bit number being processed in byte */ BYTE msgbit, keybit; /* current message and stream key bits */ ULONG64 L, R; /* left and right data blocks */ ULONG64 nR, f_out; /* get CFB1 input buffer from IV */ L = cipher->IVL; R = cipher->IVR; /* get ready to process first byte */ b = 7; /* start with top bit in byte */ *outBuffer = 0; /* and zero byte in outBuffer */ /* now loop over all bits of input */ for (j = 0; j < inputLen; j++) { msgbit = (*input >> b) & 01; /* get next msg bit */ if (debuglevel) fprintf(stderr,"%s: enCFB1(%01X,%08X%08X%08X%08X) ", NAME, msgbit, L.l, L.r, R.l, R.r); if (debuglevel > 1) fprintf(stderr,"\n"); /* compute all rounds to encrypt current CFB1 buffer */ k = 0; for (i = 0; i < ROUNDS; i++) { nR = add64(R, key->SK[k++]); /* nR = R+SK(k) */ f_out = f(nR, key->SK[k++]); /* f = f(nR,SK(k+1)) */ nR = add64(nR, key->SK[k++]); /* nR = nR+SK(k+2) */ R.l = L.l ^ f_out.l; R.r = L.r ^ f_out.r; /* R = L XOR f */ L = nR; /* L = nR */ if (debuglevel > 1) fprintf(stderr," L[%02d]=%08X%08X; R[%02d]=%08X%08X; f(SK(%02d))=%08X%08X\n", i+1, L.l, L.r, i+1, R.l, R.r, k-2, f_out.l, f_out.r); } /* undo last swap */ L = R; R = nR; /* now process msgbit by getting stream key bit, XOR in and or to out */ keybit = L.l >> 31; msgbit ^= keybit; *outBuffer |= (msgbit << b); if (debuglevel > 0) fprintf(stderr,"= %01X,%08X%08X%08X%08X\n", msgbit, L.l, L.r, R.l, R.r); /* and update the CFB1 shift register (input buffer L,R) */ L.l = (L.l << 1) | (L.r >> 31); L.r = (L.r << 1) | (R.l >> 31); R.l = (R.l << 1) | (R.r >> 31); R.r = (R.r << 1) | msgbit; /* and update bit position counter */ b--; /* and move to next input/output byte if necessary */ if (b<0) { b = 7; input++; outBuffer++; *outBuffer = 0; } } /* save new IV value */ cipher->IVL = L; cipher->IVR = R; return TRUE;}/* ....................................................................... *//* * blockDecrypt(cipher,key,input,inputLen,outBuffer) - * decrypt blocks of plaintext from input to outBuffer using cipher & key. */int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer){ /* do some basic sanity checks on params */ if (!init_done) return BAD_CIPHER_STATE; if (cipher == NULL) return BAD_CIPHER_STATE; if (key == NULL) return BAD_KEY_INSTANCE; if (key->direction != DIR_DECRYPT) return BAD_KEY_DIR; /* now call appropriate mode decrypt routine */ if (cipher->mode == MODE_ECB) return deECB(cipher, key, input, inputLen, outBuffer); else if (cipher->mode == MODE_CBC) return deCBC(cipher, key, input, inputLen, outBuffer); else if (cipher->mode == MODE_CFB1) return deCFB1(cipher, key, input, inputLen, outBuffer); else return BAD_CIPHER_MODE;}/* * decrypt blocks in ECB mode */static int deECB(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer){ int i,j,k; /* assorted loop counters */ int blocks = inputLen / (BLOCK_SIZE*8); /* compute # input blocks */ ULONG64 L, R; /* left and right data blocks */ ULONG64 nR, f_out; /* do some basic sanity checks on params */ if (inputLen % (BLOCK_SIZE*8) != 0) return BAD_CIPHER_INPUT; /* now loop over all blocks of input */ for (j = 0; j < blocks; j++) { /* pack input block into L and R */ L = byteToULONG64(input); input += 8; R = byteToULONG64(input); input += 8; if (debuglevel) fprintf(stderr,"%s: deECB(%08X%08X%08X%08X) ", NAME, L.l, L.r, R.l, R.r); if (debuglevel > 1) fprintf(stderr,"\n"); /* compute all rounds for this 1 block */ k = NUM_SUBKEYS - 1; for (i = 0; i < ROUNDS; i++) { nR = sub64(R, key->SK[k--]); /* nR = R+SK(k) */ f_out = f(nR, key->SK[k--]); /* f = f(nR,SK(k+1)) */ nR = sub64(nR, key->SK[k--]); /* nR = nR+SK(k+2) */ R.l = L.l ^ f_out.l; R.r = L.r ^ f_out.r; /* R = L XOR f */ L = nR; /* L = nR */ if (debuglevel > 1) fprintf(stderr," L[%02d]=%08X%08X; R[%02d]=%08X%08X; f(SK(%02d))=%08X%08X\n", i+1, L.l, L.r, i+1, R.l, R.r, k+2, f_out.l, f_out.r); } if (debuglevel > 0) fprintf(stderr,"= %08X%08X%08X%08X\n", R.l, R.r, L.l, L.r); /* unpack resulting L & R into output - undoing last swap */ ULONG64ToBYTE(outBuffer, R); outBuffer += 8; ULONG64ToBYTE(outBuffer, L); outBuffer += 8; } return TRUE;} /* * Dncrypt blocks in CBC mode */static int deCBC(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer){ int i,j,k; /* assorted loop counters */ int blocks = inputLen / (BLOCK_SIZE*8); /* compute # input blocks */ ULONG64 L, R; /* left and right data blocks */ ULONG64 newIVL, newIVR; /* next IV L & R halves */ ULONG64 nR, f_out; /* do some basic sanity checks on params */ if (inputLen % (BLOCK_SIZE*8) != 0) return BAD_CIPHER_INPUT; /* now loop over all blocks of input */ for (j = 0; j < blocks; j++) { /* pack input block into L and R */ L = byteToULONG64(input); input += 8; R = byteToULONG64(input); input += 8; /* save new IV value */ newIVL = L; newIVR = R; if (debuglevel) fprintf(stderr,"%s: deCBC(%08X%08X%08X%08X) ", NAME, L.l, L.r, R.l, R.r); if (debuglevel > 1) fprintf(stderr,"\n"); /* compute all rounds for this 1 block */ k = NUM_SUBKEYS - 1; for (i = 0; i < ROUNDS; i++) { nR = sub64(R, key->SK[k--]); /* nR = R+SK(k) */ f_out = f(nR, key->SK[k--]); /* f = f(nR,SK(k+1)) */ nR = sub64(nR, key->SK[k--]); /* nR = nR+SK(k+2) */ R.l = L.l ^ f_out.l; R.r = L.r ^ f_out.r; /* R = L XOR f */ L = nR; /* L = nR */ if (debuglevel > 1) fprintf(stderr," L[%02d]=%08X%08X; R[%02d]=%08X%08X; f(SK(%02d))=%08X%08X\n", i+1, L.l, L.r, i+1, R.l, R.r, k+2, f_out.l, f_out.r); } /* XOR with IV value (undoing last swap) */ R.l ^= cipher->IVL.l; R.r ^= cipher->IVL.r; L.l ^= cipher->IVR.l; L.r ^= cipher->IVR.r; /* save IV value */ cipher->IVL = newIVL; cipher->IVR = newIVR; if (debuglevel > 0) fprintf(stderr,"= %08X%08X%08X%08X\n", R.l, R.r, L.l, L.r); /* unpack resulting L & R into output - undoing last swap */ ULONG64ToBYTE(outBuffer, R); outBuffer += 8; ULONG64ToBYTE(outBuffer, L); outBuffer += 8; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -