void Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes) { u_int16_t i; u_int16_t j; u_int16_t k; u_int32_t temp; u_int32_t data[2]; j = 0; for (i = 0; i < BLF_N + 2; i++) { /* Extract 4 int8 to 1 int32 from keystream */ temp = Blowfish_stream2word(key, keybytes, &j); c->P[i] = c->P[i] ^ temp; } j = 0; data[0] = 0x00000000; data[1] = 0x00000000; for (i = 0; i < BLF_N + 2; i += 2) { Blowfish_encipher(c, data); c->P[i] = data[0]; c->P[i + 1] = data[1]; } for (i = 0; i < 4; i++) { for (k = 0; k < 256; k += 2) { Blowfish_encipher(c, data); c->S[i][k] = data[0]; c->S[i][k + 1] = data[1]; } } }
// Encode pIntput into pOutput. Input length in lSize. Returned value // is length of output which will be even MOD 8 bytes. Input buffer and // output buffer can be the same, but be sure buffer length is even MOD 8. DWORD CBlowFish::Encode (BYTE * pInput, BYTE * pOutput, DWORD lSize) { DWORD lCount, lOutSize, lGoodBytes ; BYTE *pi, *po ; int i, j ; int SameDest = (pInput == pOutput ? 1 : 0) ; lOutSize = GetOutputLength (lSize) ; for (lCount = 0 ; lCount < lOutSize ; lCount += 8) { if (SameDest) // if encoded data is being written into input buffer { if (lCount < lSize - 7) // if not dealing with uneven bytes at end { Blowfish_encipher ((DWORD *) pInput, (DWORD *) (pInput + 4)) ; } else // pad end of data with null bytes to complete encryption { po = pInput + lSize ; // point at byte past the end of actual data j = (int) (lOutSize - lSize) ; // number of bytes to set to null for (i = 0 ; i < j ; i++) *po++ = 0 ; Blowfish_encipher ((DWORD *) pInput, (DWORD *) (pInput + 4)) ; } pInput += 8 ; } else // output buffer not equal to input buffer, so must copy { // input to output buffer prior to encrypting if (lCount < lSize - 7) // if not dealing with uneven bytes at end { pi = pInput ; po = pOutput ; for (i = 0 ; i < 8 ; i++) // copy bytes to output *po++ = *pi++ ; Blowfish_encipher ((DWORD *) pOutput, // now encrypt them (DWORD *) (pOutput + 4)) ; } else // pad end of data with null bytes to complete encryption { lGoodBytes = lSize - lCount ; // number of remaining data bytes po = pOutput ; for (i = 0 ; i < (int) lGoodBytes ; i++) *po++ = *pInput++ ; for (j = i ; j < 8 ; j++) *po++ = 0 ; Blowfish_encipher ((DWORD *) pOutput, (DWORD *) (pOutput + 4)) ; } pInput += 8 ; pOutput += 8 ; } } return lOutSize ; }
int16 InitializeBlowfish(char key[], int16 keybytes) { int16 i; int16 j; int16 k; uint32 data; uint32 datal; uint32 datar; memcpy(&P, &P_values, sizeof(P_values)); memcpy(&S, &S_values, sizeof(S_values)); j = 0; for (i = 0; i < N + 2; ++i) { data = 0x00000000; for (k = 0; k < 4; ++k) { data = (data << 8) | key[j]; j = j + 1; if (j >= keybytes) { j = 0; } } P[i] = P[i] ^ data; } datal = 0x00000000; datar = 0x00000000; for (i = 0; i < N + 2; i += 2) { Blowfish_encipher(&datal, &datar); P[i] = datal; P[i + 1] = datar; } for (i = 0; i < 4; ++i) { for (j = 0; j < 256; j += 2) { Blowfish_encipher(&datal, &datar); S[i][j] = datal; S[i][j + 1] = datar; } } return 0; }
void InitBlowfish_x(void) { unsigned long data; unsigned long data1; unsigned long datar; int i,k; unsigned short j=0; /* Initialize s-boxes without file read. */ for (i=0 ;i<256;i++){ c.S[0][i]=ks0[i]; c.S[1][i]=ks1[i]; c.S[2][i]=ks2[i]; c.S[3][i]=ks3[i]; } for (i=0;i<18;i++) c.P[i]=0; for ( i=0;i<ROUNDCOUNT+2;++i){ data=0x00000000; for(k=0;k<4;++k){ data=(data<<8)|blowfish_key[j]; j++; if (j>=blowfish_keylen) j=0; } // for k c.P[i]=c.P[i]^data; } //for i data1=0x00000000; datar=0x00000000; for ( i=0;i<ROUNDCOUNT+2;i+=2){ Blowfish_encipher(&c,&data1,&datar); c.P[i]=data1; c.P[i+1]=datar; } for ( i=0;i<4;++i){ for (j=0;j<256;j+=2){ Blowfish_encipher(&c,&data1,&datar); c.S[i][j]=data1; c.S[i][j+1]=datar; }//for j }//for i }
// constructs the enctryption sieve void CBlowFish::Initialize (BYTE key[], int keybytes) { int i, j ; DWORD data, datal, datar ; union aword temp ; // first fill arrays from data tables for (i = 0 ; i < 18 ; i++) PArray [i] = bf_P[i] ; for (i = 0 ; i < 4 ; i++) { for (j = 0 ; j < 256 ; j++) SBoxes [i][j] = bf_S [i][j] ; } j = 0 ; for (i = 0 ; i < NPASS + 2 ; ++i) { temp.dword = 0 ; temp.w.byte0 = key[j]; temp.w.byte1 = key[(j+1) % keybytes] ; temp.w.byte2 = key[(j+2) % keybytes] ; temp.w.byte3 = key[(j+3) % keybytes] ; data = temp.dword ; PArray [i] ^= data ; j = (j + 4) % keybytes ; } datal = 0 ; datar = 0 ; for (i = 0 ; i < NPASS + 2 ; i += 2) { Blowfish_encipher (&datal, &datar) ; PArray [i] = datal ; PArray [i + 1] = datar ; } for (i = 0 ; i < 4 ; ++i) { for (j = 0 ; j < 256 ; j += 2) { Blowfish_encipher (&datal, &datar) ; SBoxes [i][j] = datal ; SBoxes [i][j + 1] = datar ; } } }
short InitializeBlowfish(UINT8 key[], short keybytes, BLOWFISH_KEYSCHED *keytab) { short i; /* FIXME: unsigned int, char? */ short j; /* FIXME: unsigned int, char? */ UINT32 data; UINT32 datal; UINT32 datar; union aword temp; #ifdef DEBUG_BLOWFISH fprintf (stderr, "0x%x 0x%x ", bf_P[0], bf_P[1]); fprintf (stderr, "%d %d\n", bf_P[0], bf_P[1]); #endif j = 0; for (i = 0; i < bf_N + 2; ++i) { temp.word = 0; temp.w.byte0 = key[j]; temp.w.byte1 = key[(j+1)%keybytes]; temp.w.byte2 = key[(j+2)%keybytes]; temp.w.byte3 = key[(j+3)%keybytes]; data = temp.word; keytab->P[i] = keytab->P[i] ^ data; j = (j + 4) % keybytes; } datal = 0x00000000; datar = 0x00000000; for (i = 0; i < bf_N + 2; i += 2) { Blowfish_encipher(&datal, &datar, keytab); keytab->P[i] = datal; keytab->P[i + 1] = datar; } for (i = 0; i < 4; ++i) { for (j = 0; j < 256; j += 2) { Blowfish_encipher(&datal, &datar, keytab); keytab->S[i][j] = datal; keytab->S[i][j + 1] = datar; } } return 0; }
// Encode pIntput into pOutput. Input length in lSize. Returned value // is length of output which will be even MOD 8 bytes. Input buffer and // output buffer can be the same, but be sure buffer length is even MOD 8. DWORD CBlowFish::Encode (BYTE * pInput, BYTE * pOutput, DWORD lSize) { DWORD lCount, lOutSize, *dwOutput = (DWORD *)pOutput; _int64 CBCval = 0; if (pInput != pOutput) memcpy(pOutput, pInput, lSize); lOutSize = GetOutputLength(lSize); memset(pOutput + lSize, mode == CBC ? lOutSize - lSize : 0, lOutSize - lSize); for (lCount = 0; lCount < lOutSize; lCount += 8) { if (mode == CBC) *(_int64 *)dwOutput ^= CBCval; change_order(dwOutput); change_order(dwOutput + 1); Blowfish_encipher(dwOutput, dwOutput + 1); change_order(dwOutput); change_order(dwOutput + 1); if (mode == CBC) CBCval = *(_int64 *)dwOutput; dwOutput += 2; } return lOutSize; }
void blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) { u_int32_t l, r, d[2]; u_int32_t i; for (i = 0; i < len; i += 8) { l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; d[0] = l; d[1] = r; Blowfish_encipher(c, d); l = d[0]; r = d[1]; data[0] = l >> 24 & 0xff; data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = r >> 24 & 0xff; data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; data += 8; } }
// Encode pIntput into pOutput. Input length in lSize. Returned value // is length of output which will be even MOD 8 bytes. Input buffer and // output buffer can be the same, but be sure buffer length is even MOD 8. DWORD CBlowFish::Encode (BYTE * pInput, BYTE * pOutput, DWORD lSize) { DWORD lCount, lOutSize, dx; int SameDest=(pInput==pOutput ? 1 : 0); // if input differs from output copy input to output if (!SameDest) for (dx=0;dx<lSize;dx++) pOutput[dx]=pInput[dx]; // if the size isn't dividable by 8 pad the end of output with zeros if (lSize%8) { for (dx=0;dx<8-lSize%8;dx++) pOutput[lSize+dx]=0; lOutSize=lSize+dx; } else lOutSize=lSize; // big endian hotfix, reverse the byte order of every 4 byte block #ifdef HAVE_BIG_ENDIAN BYTE *temp=pOutput; mix(pOutput,lOutSize); #endif // now we have the correct thing to encode for (lCount=0;lCount<lOutSize;lCount+=8) { Blowfish_encipher((DWORD *)pOutput, (DWORD *)(pOutput+4)); pOutput+=8; } // change the order back #ifdef HAVE_BIG_ENDIAN mix(temp,lOutSize); #endif return lOutSize ; }
void blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len) { u_int32_t l, r, d[2]; u_int32_t i, j; for (i = 0; i < len; i += 8) { for (j = 0; j < 8; j++) data[j] ^= iv[j]; l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; d[0] = l; d[1] = r; Blowfish_encipher(c, d); l = d[0]; r = d[1]; data[0] = l >> 24 & 0xff; data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = r >> 24 & 0xff; data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; iv = data; data += 8; } }
// Encrypt pIntput into pOutput. Input length in lSize. Returned value // is length of output which will be even MOD 8 bytes. Input buffer and // output buffer can be the same, but be sure buffer length is even MOD 8. DWORD CBlowFish::Encrypt(const BYTE *pInput, BYTE *pOutput, DWORD lSize, int mode, _int64 IV) { DWORD lCount, lOutSize, *dwOutput = (DWORD *)pOutput; if (pInput != pOutput) memcpy(pOutput, pInput, lSize); lOutSize = GetOutputLength(lSize, mode); memset(pOutput + lSize, (mode & BF_PKCS5) ? lOutSize - lSize : 0, lOutSize - lSize); for (lCount = 0; lCount < lOutSize; lCount += BF_BLKSIZE) { if (mode & BF_CBC) *(_int64 *)dwOutput ^= IV; change_order(dwOutput); change_order(dwOutput + 1); Blowfish_encipher(dwOutput, dwOutput + 1); change_order(dwOutput); change_order(dwOutput + 1); if (mode & BF_CBC) IV = *(_int64 *)dwOutput; dwOutput += 2; } return lCount; }
void CPacketUtils::EncryptPacket(PacketData& packet) { if(packet.size() <= sizeof(PACKETHEADER)) { assert(0); return; } uint8* data = &packet[0]; uint32 size = packet.size(); data += 0x10; size -= 0x10; while(1) { uint32 subPacketSize = *reinterpret_cast<uint16*>(data); size -= subPacketSize; subPacketSize -= 0x10; data += 0x10; for(unsigned int i = 0; i < subPacketSize; i += 8) { Blowfish_encipher( reinterpret_cast<uint32*>(data + i), reinterpret_cast<uint32*>(data + i + 4)); } data += subPacketSize; if(size == 0) break; } }
void BlowFish::Encrypt(const unsigned char *in, unsigned char *out) { for (int x = 0; x < 8; x++) out[x] = in[x]; Blowfish_encipher(reinterpret_cast<uint32 *>(out), reinterpret_cast<uint32 *>(out + sizeof(uint32))); }
// constructs the enctryption sieve void CBlowFish::Initialize(const BYTE *key, int keybytes) { int i, j; DWORD datal, datar; union aword temp; // first fill arrays from data tables for (i = 0; i < NPASS + 2; i++) PArray[i] = bf_P[i]; for (i = 0; i < 4; i++) { for (j = 0; j < 256; j++) SBoxes[i][j] = bf_S[i][j]; } for (i=0, j=0; i < NPASS + 2; i++) { temp.w.byte0 = key[j++ % keybytes]; temp.w.byte1 = key[j++ % keybytes]; temp.w.byte2 = key[j++ % keybytes]; temp.w.byte3 = key[j++ % keybytes]; PArray[i] ^= temp.dword; } datal = datar = 0; for (i = 0; i < NPASS + 2; i += 2) { Blowfish_encipher(&datal, &datar); PArray[i] = datal; PArray[i + 1] = datar; } for (i = 0; i < 4; i++) { for (j = 0; j < 256; j += 2) { Blowfish_encipher(&datal, &datar); SBoxes[i][j] = datal; SBoxes[i][j + 1] = datar; } } }
//Initialize with Key void BlowFish::InitializeBlowfish(const TUint8 key[], TInt16 keybytes) { TInt16 i; TInt16 j; TUint32 data; TUint32 datal; TUint32 datar; union aword temp; j = 0; for (i = 0; i < bf_N + 2; ++i) { temp.word = 0; temp.w.byte0 = key[j]; temp.w.byte1 = key[(j+1)%keybytes]; temp.w.byte2 = key[(j+2)%keybytes]; temp.w.byte3 = key[(j+3)%keybytes]; data = temp.word; bf_P[i] = bf_P[i] ^ data; j = (j + 4) % keybytes; } datal = 0x00000000; datar = 0x00000000; for (i = 0; i < bf_N + 2; i += 2) { Blowfish_encipher(&datal, &datar); bf_P[i] = datal; bf_P[i + 1] = datar; } for (i = 0; i < 4; ++i) { for (j = 0; j < 256; j += 2) { Blowfish_encipher(&datal, &datar); bf_S[i][j] = datal; bf_S[i][j + 1] = datar; } } }
void blf_enc(blf_ctx *c,unsigned long *data,int blocks){ unsigned long *d; int i; d=data; for (i=0;i<blocks;i++){ Blowfish_encipher(c,d,d+1); d+=2; } }
void Blowfish_expandstate(ssh_blf_ctx *c, const uint8_t *data, uint16_t databytes, const uint8_t *key, uint16_t keybytes) { uint16_t i; uint16_t j; uint16_t k; uint32_t temp; uint32_t datal; uint32_t datar; j = 0; for (i = 0; i < BLF_N + 2; i++) { /* Extract 4 int8 to 1 int32 from keystream */ temp = Blowfish_stream2word(key, keybytes, &j); c->P[i] = c->P[i] ^ temp; } j = 0; datal = 0x00000000; datar = 0x00000000; for (i = 0; i < BLF_N + 2; i += 2) { datal ^= Blowfish_stream2word(data, databytes, &j); datar ^= Blowfish_stream2word(data, databytes, &j); Blowfish_encipher(c, &datal, &datar); c->P[i] = datal; c->P[i + 1] = datar; } for (i = 0; i < 4; i++) { for (k = 0; k < 256; k += 2) { datal ^= Blowfish_stream2word(data, databytes, &j); datar ^= Blowfish_stream2word(data, databytes, &j); Blowfish_encipher(c, &datal, &datar); c->S[i][k] = datal; c->S[i][k + 1] = datar; } } }
void ssh_blf_enc(ssh_blf_ctx *c, uint32_t *data, uint16_t blocks) { uint32_t *d; uint16_t i; d = data; for (i = 0; i < blocks; i++) { Blowfish_encipher(c, d, d + 1); d += 2; } }
void blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks) { u_int32_t *d; u_int16_t i; d = data; for (i = 0; i < blocks; i++) { Blowfish_encipher(c, d); d += 2; } }
void BlowFish::InitializeBlowfish(const unsigned char key[], short keybytes) { short i; short j; uint32 data; uint32 datal; uint32 datar; union aword temp; j = 0; for (i = 0; i < bf_N + 2; ++i) { temp.word = 0; temp.w.byte0 = key[j]; temp.w.byte1 = key[(j+1)%keybytes]; temp.w.byte2 = key[(j+2)%keybytes]; temp.w.byte3 = key[(j+3)%keybytes]; data = temp.word; bf_P[i] ^= data; j = short((j + 4) % keybytes); } datal = datar = 0x00000000; for (i = 0; i < bf_N + 2; i += 2) { Blowfish_encipher(&datal, &datar); bf_P[i] = datal; bf_P[i + 1] = datar; } for (i = 0; i < 4; ++i) { for (j = 0; j < 256; j += 2) { Blowfish_encipher(&datal, &datar); bf_S[i][j] = datal; bf_S[i][j + 1] = datar; } } }
void CCryptMgr::Encrypt(istream& is, ostream& os) #endif // VC7 { int n = 0; char buf[8]; while (!is.eof()) { memset(buf, 0, 8); is.read(buf, 8); n = is.gcount(); Blowfish_encipher((UWORD_32bits*)buf, (UWORD_32bits*)&buf[4]); os.write(buf, 8); } os.put((char)n); }
void blf_encrypt(struct keystate *ks, u_int8_t *data, u_int16_t len) { u_int16_t i, blocksize = ks->xf->blocksize; u_int8_t *iv = ks->liv; u_int32_t xl, xr; memcpy(iv, ks->riv, blocksize); for (i = 0; i < len; data += blocksize, i += blocksize) { XOR64(data, iv); xl = GET_32BIT_BIG(data); xr = GET_32BIT_BIG(data + 4); Blowfish_encipher(&ks->ks_blf, &xl, &xr); SET_32BIT_BIG(data, xl); SET_32BIT_BIG(data + 4, xr); SET64(iv, data); } }
void ssh_blf_ecb_encrypt(ssh_blf_ctx *c, uint8_t *data, uint32_t len) { uint32_t l, r; uint32_t i; for (i = 0; i < len; i += 8) { l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_encipher(c, &l, &r); data[0] = l >> 24 & 0xff; data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = r >> 24 & 0xff; data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; data += 8; } }
void CPacketUtils::EncryptPacket(PacketData& packet) { if (packet.size() <= sizeof(PACKETHEADER)) { assert(0); return; } uint8_t* data = &packet[0]; uint32_t size = (uint32_t)packet.size(); data += sizeof(PACKETHEADER); size -= sizeof(PACKETHEADER); if (size % 8 != 0) { return; } while (1) { SUBPACKETHEADER subPacket = *reinterpret_cast<SUBPACKETHEADER*>(data); uint32_t subPacketSize = subPacket.subPacketSize; size -= subPacketSize; subPacketSize -= sizeof(SUBPACKETHEADER); data += sizeof(SUBPACKETHEADER); for (unsigned int i = 0; i < subPacketSize; i += 8) { Blowfish_encipher( reinterpret_cast<uint32_t*>(data + i), reinterpret_cast<uint32_t*>(data + i + 4)); } data += subPacketSize; if (size == 0) break; } }
void ssh_blf_cbc_encrypt(ssh_blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len) { uint32_t l, r; uint32_t i, j; for (i = 0; i < len; i += 8) { for (j = 0; j < 8; j++) data[j] ^= iv[j]; l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_encipher(c, &l, &r); data[0] = l >> 24 & 0xff; data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = r >> 24 & 0xff; data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; iv = data; data += 8; } }
// constructs the encryption sieve bool BlowfishPIMPL::Initialize(void * key_ptr, uint8_t key_size) { if(key_size == 0 || key_size > MAXKEYBYTES) { return false; } if(!key_ptr) { return false; } uint8_t * key = reinterpret_cast<uint8_t *>(key_ptr); uint32_t i, j; uint32_t data, datal, datar; union aword temp; // first fill arrays from data tables for(i = 0; i < 18; i++) { PArray [i] = bf_P [i]; } for(i = 0; i < 4; i++) { for(j = 0; j < 256; j++) { SBoxes [i][j] = bf_S [i][j]; } } j = 0; for(i = 0; i < NPASS + 2; ++i) { temp.dword = 0; temp.w.byte0 = key[j]; temp.w.byte1 = key[(j+1) % key_size]; temp.w.byte2 = key[(j+2) % key_size]; temp.w.byte3 = key[(j+3) % key_size]; data = temp.dword; PArray [i] ^= data; j =(j + 4) % key_size; } datal = 0; datar = 0; for(i = 0; i < NPASS + 2; i += 2) { Blowfish_encipher(&datal, &datar); PArray [i] = datal; PArray [i + 1] = datar; } for(i = 0; i < 4; ++i) { for(j = 0; j < 256; j += 2) { Blowfish_encipher(&datal, &datar); SBoxes[i][j] = datal; SBoxes[i][j + 1] = datar; } } return true; }
short InitializeBlowfish(blf_ctx *bc, unsigned char key[], int keybytes) { short i; short j; short k; unsigned long data; unsigned long datal; unsigned long datar; /* initialise p & s-boxes without file read */ for (i = 0; i < N+2; i++) { bc->P[i] = bfp[i]; } for (i = 0; i < 256; i++) { bc->S[0][i] = ks0[i]; bc->S[1][i] = ks1[i]; bc->S[2][i] = ks2[i]; bc->S[3][i] = ks3[i]; } j = 0; for (i = 0; i < N + 2; ++i) { data = 0x00000000; for (k = 0; k < 4; ++k) { data = (data << 8) | key[j]; j = j + 1; if (j >= keybytes) { j = 0; } } bc->P[i] = bc->P[i] ^ data; } datal = 0x00000000; datar = 0x00000000; for (i = 0; i < N + 2; i += 2) { Blowfish_encipher(bc, &datal, &datar); bc->P[i] = datal; bc->P[i + 1] = datar; } for (i = 0; i < 4; ++i) { for (j = 0; j < 256; j += 2) { Blowfish_encipher(bc, &datal, &datar); bc->S[i][j] = datal; bc->S[i][j + 1] = datar; } } return 0; }
// Encode pIntput into pOutput. Input length in lSize. Returned value // is length of output which will be even MOD 8 bytes. Input buffer and // output buffer can be the same, but be sure buffer length is even MOD 8. bool BlowfishPIMPL::Encode(const void * const input_ptr, uint64_t input_size, void * output_ptr, uint64_t output_size) { uint64_t lCount, lOutSize, lGoodBytes; uint8_t * pi, * po; uint64_t i, j; bool sameDest = (input_ptr == output_ptr); uint8_t * pInput = reinterpret_cast<uint8_t *>(const_cast<void *>(input_ptr)); uint8_t * pOutput = reinterpret_cast<uint8_t *>(output_ptr); if(!input_ptr || !output_ptr) { return false; } lOutSize = GetOutputLength(input_size); if(output_size < lOutSize) { return false; } for(lCount = 0; lCount < lOutSize; lCount += 8) { if(sameDest) // if encoded data is being written into input buffer { if(lCount < input_size - 7) // if not dealing with uneven bytes at end { Blowfish_encipher(reinterpret_cast<uint32_t *>(pInput), reinterpret_cast<uint32_t *>(pInput + 4)); } else // pad end of data with null bytes to complete encryption { po = pInput + input_size; // point at byte past the end of actual data j = lOutSize - input_size; // number of bytes to set to null for(i = 0; i < j; i++) *po++ = 0; Blowfish_encipher(reinterpret_cast<uint32_t *>(pInput), reinterpret_cast<uint32_t *>(pInput + 4)); } pInput += 8; } else // output buffer not equal to input buffer, so must copy { // input to output buffer prior to encrypting if(lCount < input_size - 7) // if not dealing with uneven bytes at end { pi = pInput; po = pOutput; for(i = 0; i < 8; i++) // copy bytes to output *po++ = *pi++; // now encrypt them Blowfish_encipher(reinterpret_cast<uint32_t *>(pOutput), reinterpret_cast<uint32_t *>(pOutput + 4)); } else // pad end of data with null bytes to complete encryption { lGoodBytes = input_size - lCount; // number of remaining data bytes po = pOutput; for(i = 0; i < lGoodBytes; i++) *po++ = *pInput++; for(j = i; j < 8; j++) *po++ = 0; Blowfish_encipher(reinterpret_cast<uint32_t *>(pOutput), reinterpret_cast<uint32_t *>(pOutput + 4)); } pInput += 8; pOutput += 8; } } return true; }