s3fs::Crypto::Crypto() { // FGPRINT("s3fs::Crypto Initializing a crypto object\n"); // SYSLOGERR("s3fs::Crypto Initializing a crypto object"); gen_key(); gen_iv(); }
/* send encrypted packet */ int vpn_send(int fd, vpn_crypt_t *cry, vpn_proto_t type, const void *buf, size_t buflen) { vpn_hdr_t hdr; gcry_cipher_hd_t hd = NULL; char bigpack[VPN_BIGPACKET], encpack[VPN_BIGPACKET], xiv[256], *s; int pad = ~((buflen % cry->blklen) - cry->blklen)+1; int re, rs, rc, rx; switch(type) { case VPN_CLIENT: hd = cry->hsrc; break; case VPN_SERVER: hd = cry->hdst; } /* fill header */ hdr.pad = pad == cry->blklen ? 0 : pad; hdr.checksum = buflen + hdr.pad; /* check buffer size */ if(sizeof(bigpack) < hdr.checksum) return xmsg(-1, VPN_DEBUG|VPN_INFO, "packet too big to send: %d data bytes + %d header bytes\n", buflen, sizeof(hdr)); /* copy data to `bigpack' */ memset(bigpack, 0, sizeof(bigpack)); memcpy(&bigpack, buf, buflen); if(!cry->rndsend) cry->rndsend = initial_iv_random; memset(xiv, 0, sizeof(xiv)); gen_iv(xiv, cry->blklen, cry->rndsend); /* xmsg(0, VPN_DEBUG, "send using iv: %s\n", xiv); */ re = xencrypt(hd, cry->blklen, xiv, encpack, sizeof(encpack), bigpack, hdr.checksum); if(re == -1 || re != hdr.checksum) return xmsg(-1, VPN_DEBUG|VPN_INFO, "vpn_send: cannot encrypt packet (%d != %d)\n", re, hdr.checksum); /* send header */ rs = send(fd, &hdr, sizeof(hdr), 0); if(rs == -1) return rs; else if(!rs) return xmsg(0, VPN_DEBUG|VPN_INFO, "vpn_send: lost connection, peer disconnected\n"); else if(rs != sizeof(hdr)) return xmsg(-1, VPN_DEBUG|VPN_INFO, "vpn_send: partial send of header not allowed\n"); xmsg(0, VPN_DEBUG, "sent %d bytes header, checksum=%d and pad=%d\n", rs, hdr.checksum, hdr.pad); /* send data */ s = encpack; rc = re; rx = 0; do { rs = safe_send(fd, s, rc); if(rs == -1) return rs; else if(!rs) return xmsg(0, VPN_DEBUG|VPN_INFO, "vpn_send: lost connection, peer disconnected\n"); xmsg(0, VPN_DEBUG, "sent %d bytes of packet...\n", rs); s += rs; rx += rs; rc -= rs; } while(rx < re); cry->rndsend = buflen; return buflen; }
int vpn_recv(int fd, vpn_crypt_t *cry, vpn_proto_t type, void *buf, size_t buflen) { vpn_hdr_t hdr; gcry_cipher_hd_t hd = NULL; char bigpack[VPN_BIGPACKET], decpack[VPN_BIGPACKET], xiv[256], *s; int rr, rd, rc, rx; switch(type) { case VPN_CLIENT: hd = cry->hsrc; break; case VPN_SERVER: hd = cry->hdst; } memset(bigpack, 0, sizeof(bigpack)); memset(decpack, 0, sizeof(decpack)); /* read packet header */ memset(&hdr, 0, sizeof(hdr)); rr = recv(fd, &hdr, sizeof(hdr), 0); if(rr == -1) return rr; else if(!rr) return xmsg(0, VPN_DEBUG|VPN_INFO, "vpn_recv: lost connection, peer disconnected\n"); else if(rr != sizeof(hdr)) return xmsg(-1, VPN_DEBUG|VPN_INFO, "vpn_recv: partial recv of header not allowed\n"); xmsg(0, VPN_DEBUG, "received %d bytes header, checksum=%d and pad=%d\n", rr, hdr.checksum, hdr.pad); if(hdr.checksum > sizeof(bigpack)) return xmsg(-1, VPN_DEBUG|VPN_INFO, "packet too big: header checksum is %d\n", hdr.checksum); /* read packet data */ s = bigpack; rc = hdr.checksum; rx = 0; do { rr = safe_recv(fd, s, rc); if(rr == -1) return rr; else if(!rr) return xmsg(0, VPN_DEBUG|VPN_INFO, "vpn_recv: lost connection, peer disconnected\n"); xmsg(0, VPN_DEBUG, "read %d bytes of packet...\n", rr); s += rr; rx += rr; rc -= rr; } while(rx < hdr.checksum); /* generate iv to decrypt */ if(!cry->rndrecv) cry->rndrecv = initial_iv_random; memset(xiv, 0, sizeof(xiv)); gen_iv(xiv, cry->blklen, cry->rndrecv); /* xmsg(0, VPN_DEBUG, "recv using iv: %s\n", xiv); */ /* decrypt */ rd = xdecrypt(hd, cry->blklen, xiv, decpack, sizeof(decpack), bigpack, hdr.checksum); if(rd == -1 || rd != hdr.checksum) return xmsg(-1, VPN_DEBUG|VPN_INFO, "vpn_recv: cannot decrypt packet (%d != %d)\n", rd, hdr.checksum); /* copy data to user */ memcpy(buf, decpack, hdr.checksum - hdr.pad); /* set next iv */ cry->rndrecv = hdr.checksum - hdr.pad; return hdr.checksum - hdr.pad; }
/* @func encrypt infile to outfile, using filephrase to generate the key, and optionally using masterphrase as the master key */ int encrypt(char *infile,char *outfile,char *filephrase,char *masterphrase) { int err=0; FILE *in = NULL; if (fopen_s(&in, infile, "rb") != 0) { printf("input file %s can't be opened\1", infile); err++; } else { FILE *out = NULL; if (fopen_s(&out, outfile, "wb") != 0) { printf("output file %s can't be opened\n", outfile); err++; } else { BYTE buffer[BLOCKSIZE]; unsigned long preamble[] = { PREAMBLE, FILEKEY_FORMAT}; BYTE iv[AES_MAX_IV_SIZE]; BYTE filekey[KEY_BYTES]; BOOL masterformat = masterphrase && *masterphrase; AES_cipherInstance cipher; AES_keyInstance key; if(masterformat) { preamble[1]=MASTERKEY_FORMAT; } gen_iv(iv,sizeof(iv)); // generate a random iv AES_keygen(filephrase,filekey); // make key file passphrase fwrite(preamble,1,sizeof(preamble),out); // write the preamble fwrite(iv,1,sizeof(iv),out); // and the iv AES_bin_setup(&key,AES_DIR_ENCRYPT,KEY_BYTES*8,filekey); // prepare the encryption AES_bin_cipherInit(&cipher,AES_MODE_CBC,iv); if(masterformat) { // encrypt the file key with the masterkey and write it. BYTE masteriv[AES_MAX_IV_SIZE]; BYTE masterkey[KEY_BYTES]; BYTE encfilekey[KEY_BYTES]; AES_cipherInstance mastercipher; AES_keyInstance mkey; AES_keygen(masterphrase,masterkey); // generate the master key gen_iv(masteriv,sizeof(masteriv)); // and an iv for it AES_bin_setup(&mkey,AES_DIR_ENCRYPT,KEY_BYTES*8,masterkey); AES_bin_cipherInit(&mastercipher,AES_MODE_CBC,masteriv); // encrypt the file key using the master key AES_blockEncrypt(&mastercipher,&mkey,filekey,sizeof(filekey),encfilekey); fwrite(masteriv,1,sizeof(masteriv),out); fwrite(encfilekey,1,sizeof(encfilekey),out); } // now encrypt and output the actual data { long bytesread=0; long bytesencrypted=0; do { bytesread = (long)fread(buffer,1,sizeof(buffer),in); bytesencrypted=0; if(bytesread>0) { bytesencrypted = AES_blockEncrypt(&cipher,&key,buffer,bytesread,buffer); fwrite(buffer,1,bytesencrypted,out); } } while((bytesread>0)&&(bytesencrypted==bytesread)); // pad the last block bytesencrypted = AES_padEncrypt(&cipher,&key,buffer+bytesencrypted,(bytesread-bytesencrypted),buffer); fwrite(buffer,1,bytesencrypted,out); fclose(out); } } fclose(in); } return(err); }