bool handleKeys(arguments* args, ThreefishKey_t* cipher_context, MacCtx_t* mac_context) { pdebug("handleKeys()\n"); //sanity check if (args == NULL || cipher_context == NULL || mac_context == NULL) { return false; } const uint64_t block_byte_size = (uint64_t)args->state_size/8; uint64_t* cipher_key = NULL; uint64_t* mac_key = NULL; //no hash password (bad idea) if (args->hash == false && args->hash_from_file == false) { cipher_key = noHashKey(args->password, args->pw_length, args->state_size); } //no hash from file (bad idea) else if (args->hash == false && args->hash_from_file == true) { cipher_key = noHashBlockFromFile(args->key_file, args->state_size); } //hash user entered password to be hashed else if (args->hash == true && args->hash_from_file == false) { cipher_key = (uint64_t*)keyHash(args->password, args->pw_length, args->state_size); } //hash user entered password from file else if (args->hash == true && args->hash_from_file == true) { printf("Hashing key from file... "); cipher_key = hashKeyFromFile(args->key_file, args->state_size); printf("Done\n"); } if (cipher_key == NULL) { return false; } //failure //Generate IV if we are encrypting if (args->encrypt == true) { if (genIV(args) == false) { return false; } //can't continue without an IV } else //and get it from the first part of the file if we are decrypting { if (getIV(args) == false) { return false; } } //stretch the key with scrypt if (args->hash == true && args->legacy_hash == false) { printf("Stretching key this may take a bit... "); if (kdf_scrypt((uint8_t*)cipher_key, (size_t)(args->state_size/8), (uint8_t*)args->iv, (size_t)(args->state_size/8), SCRYPT_N, SCRYPT_R, SCRYPT_P, (uint8_t*)cipher_key, (size_t)(args->state_size/8) ) != 0) { return false; } //scrypt failed printf("Done\n"); } //generate the mac key from the cipher_key mac_key = (uint64_t*)keyHash((uint8_t*)cipher_key, block_byte_size, args->state_size); //initialize the key structure for the cipher key threefishSetKey(cipher_context, (ThreefishSize_t)args->state_size, cipher_key, threefizer_tweak); //initialize the mac context and undelying skein structures InitMacCtx(args, mac_context, mac_key); //free allocated resources if (cipher_key != NULL) { free(cipher_key); } if (mac_key != NULL) { free(mac_key); } return true; }
/*****************child process encrypt udp connection*******************/ void udp_vpn(int MODE, int Port, char *ip, int port, int pipefd) { struct sockaddr_in sin, sout;//standard in and out sockets address struct ifreq ifr;//virtual nic card socklen_t soutlen; int fd, s, l, i, ready = 0; int status; fd_set fdset; char buf[BUFSIZE], hash[HASHLEN], totalbuf[BUFSIZE]; //set up virtual nic card if ((fd = open("/dev/net/tun", O_RDWR)) < 0) PERROR("open error!!!"); memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; strncpy(ifr.ifr_name, "toto%d", IFNAMSIZ); if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) PERROR("ioctl"); printf("Allocated interface %s. Configure and use it\n", ifr.ifr_name); //create udp socket s = socket(PF_INET, SOCK_DGRAM, 0); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(Port); //bind step if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) PERROR("bind error!!!"); soutlen = sizeof(sout); if (MODE == CLIENT) { sout.sin_family = AF_INET; sout.sin_port = htons(port); inet_aton(ip, &sout.sin_addr); } while (1) { //read the key l = read(pipefd, buf, sizeof(buf)); if (l > 0) { if (buf[0] == 'a') { //disconnect exit(0); } else if (buf[0]=='k') { //getting key memcpy(key, buf + 1, KEYSIZE); ready = 1; } } if (!ready) { sleep(1); continue; } //fd from nic card, s from socket FD_ZERO(&fdset); FD_SET(fd, &fdset); FD_SET(s, &fdset); if (select(fd+s+1, &fdset,NULL,NULL,NULL) < 0) PERROR("select");//select which file descriptor is using //virtual nic card if (FD_ISSET(fd, &fdset)) { if (DEBUG) printf("SENT: "); l = read(fd, buf, BUFSIZE); if (l < 0) PERROR("read"); if (DEBUG) { printf("\nplain payload: "); for(i = 0; i < l; i++) printf("%02x", *(buf+i)); printf("\n"); } genIV(IV); //encrypt, hash, append, and send to client if (do_crypt(key, IV, buf, &l, 1)) { if (DEBUG) { printf("\nencrypted payload: "); for(i = 0; i < l; i++) printf("%02x", *(buf+i)); printf("\n"); } memcpy(totalbuf, IV, IVSIZE); memcpy(totalbuf+IVSIZE, buf, BUFSIZE-IVSIZE); l+=IVSIZE; appendHash(totalbuf, &l); if (DEBUG) { printf("\nfinal payload: "); for(i = 0; i < l; i++) printf("%02x", *(buf+i)); printf("\n"); } //send to client if (sendto(s, totalbuf, l, 0, (struct sockaddr *)&sout, soutlen) < 0) PERROR("sendto"); } else { printf("encrypt error\n"); } } //socket else { if (DEBUG) printf("\n RECEIVED"); l = recvfrom(s, buf, BUFSIZE, 0, (struct sockaddr *)&sout, &soutlen); if (DEBUG) { printf("\n(encrypted) payload: "); for(i = 0; i < l; i++) printf("%02x", *(buf+i)); putchar(10); } //check reliability if (checkHash(buf, &l)) { printf("HASH mismatch.\n"); } else { memcpy(IV, buf, IVSIZE); if (DEBUG) { printf("\nhash checked payload: "); for(i = 0; i < l; i++) printf("%02x", *(buf+i)); putchar(10); } l-=IVSIZE; //decrypt and send to virtual nic card if (do_crypt(key, IV, buf+IVSIZE, &l, 0)) { if (DEBUG) { printf("\nfinal plain payload: "); for(i = 0; i < l; i++) printf("%02x", *(buf+i)); putchar(10); } if (write(fd, buf+IVSIZE, l) < 0) PERROR("write"); } else { printf("decrypt error\n"); } } } } }