int zmq::curve_server_t::produce_ready (msg_t *msg_) { uint8_t ready_nonce [crypto_box_NONCEBYTES]; uint8_t ready_plaintext [crypto_box_ZEROBYTES + 256]; uint8_t ready_box [crypto_box_BOXZEROBYTES + 16 + 256]; // Create Box [metadata](S'->C') memset (ready_plaintext, 0, crypto_box_ZEROBYTES); uint8_t *ptr = ready_plaintext + crypto_box_ZEROBYTES; // Add socket type property const char *socket_type = socket_type_string (options.type); ptr += add_property (ptr, "Socket-Type", socket_type, strlen (socket_type)); // Add identity property if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER || options.type == ZMQ_ROUTER) ptr += add_property (ptr, "Identity", options.identity, options.identity_size); const size_t mlen = ptr - ready_plaintext; memcpy (ready_nonce, "CurveZMQREADY---", 16); memcpy (ready_nonce + 16, &cn_nonce, 8); int rc = crypto_box_afternm (ready_box, ready_plaintext, mlen, ready_nonce, cn_precom); zmq_assert (rc == 0); rc = msg_->init_size (14 + mlen - crypto_box_BOXZEROBYTES); errno_assert (rc == 0); uint8_t *ready = static_cast <uint8_t *> (msg_->data ()); memcpy (ready, "\x05READY", 6); // Short nonce, prefixed by "CurveZMQREADY---" memcpy (ready + 6, &cn_nonce, 8); // Box [metadata](S'->C') memcpy (ready + 14, ready_box + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES); cn_nonce++; return 0; }
/* Fast encrypt. Depends on enc_key from encrypt_precompute. */ int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted) { if (length + crypto_box_MACBYTES > MAX_DATA_SIZE || length == 0) return -1; uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES] = {0}; uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_BOXZEROBYTES]; memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes. crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, enc_key); if (crypto_iszero(temp_encrypted, crypto_box_BOXZEROBYTES) != 0) return -1; /* Unpad the encrypted message. */ memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; }
int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, size_t length, uint8_t *encrypted) { if (length == 0 || !secret_key || !nonce || !plain || !encrypted) { return -1; } uint8_t temp_plain[length + crypto_box_ZEROBYTES]; uint8_t temp_encrypted[length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES]; memset(temp_plain, 0, crypto_box_ZEROBYTES); memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes. if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, secret_key) != 0) { return -1; } /* Unpad the encrypted message. */ memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); return length + crypto_box_MACBYTES; }
// enc_msg = crypto_secretbox(msg, nonce, shared_secret); static int tweetnacl_crypto_secretbox( lua_State* L ) { unsigned int msg_len; const char* msg = luaL_checklstring(L,1,&msg_len); if(msg_len < 1) return luaL_error( L, "len(message)=%d, too short", msg_len); unsigned int nonce_len; const char* nonce = luaL_checklstring(L,2,&nonce_len); if(nonce_len != crypto_box_NONCEBYTES) return luaL_error( L, "len(nonce)=%d, should be %d", nonce_len, crypto_box_NONCEBYTES); unsigned int secret_len; const char* secret = luaL_checklstring(L,3,&secret_len); if(secret_len != crypto_box_BEFORENMBYTES) return luaL_error( L, "len(secret)=%d, should be %d", secret_len, crypto_box_BEFORENMBYTES); unsigned int cmsg_len = msg_len + crypto_box_ZEROBYTES; char *cmsg = (char *)c_malloc(cmsg_len); if(!cmsg) return luaL_error( L, "malloc failed, %d bytes", cmsg_len); int i; for(i=0;i<crypto_box_ZEROBYTES;i++) cmsg[i] = 0; for(;i<cmsg_len;i++) cmsg[i] = msg[i-crypto_box_ZEROBYTES]; unsigned int emsg_len = cmsg_len; char *emsg = (char *)c_malloc(emsg_len); if(!emsg) { c_free(cmsg); return luaL_error( L, "malloc failed, %d bytes", emsg_len); } crypto_box_afternm(emsg, cmsg, cmsg_len, nonce, secret); lua_pushlstring(L, emsg+crypto_box_BOXZEROBYTES, emsg_len-crypto_box_BOXZEROBYTES); c_free(cmsg); c_free(emsg); return 1; }
ssize_t curve25519_encode(struct curve25519_struct *c, struct curve25519_proto *p, unsigned char *plaintext, size_t size, unsigned char **chipertext) { int ret, i; ssize_t done = size; struct taia packet_taia; spinlock_lock(&c->enc_lock); if (unlikely(size > c->enc_buf_size)) { spinlock_unlock(&c->enc_lock); return -ENOMEM; } taia_now(&packet_taia); taia_pack(p->enonce + NONCE_OFFSET, &packet_taia); memset(c->enc_buf, 0, c->enc_buf_size); ret = crypto_box_afternm(c->enc_buf, plaintext, size, p->enonce, p->key); if (unlikely(ret)) { spinlock_unlock(&c->enc_lock); return -EIO; } memcpy(c->enc_buf + crypto_box_boxzerobytes - NONCE_LENGTH, p->enonce + NONCE_OFFSET, NONCE_LENGTH); for (i = 0; i < crypto_box_boxzerobytes - NONCE_LENGTH; ++i) c->enc_buf[i] = (uint8_t) mt_rand_int32(); (*chipertext) = c->enc_buf; spinlock_unlock(&c->enc_lock); return done; }
static int _handle_initiate (struct curvecpr_server *server, struct curvecpr_session *s, void *priv, const struct curvecpr_packet_initiate *p, const unsigned char *buf, size_t num) { const struct curvecpr_server_cf *cf = &server->cf; unsigned char nonce[24]; unsigned char data[sizeof(struct curvecpr_packet_initiate_box) + 640]; if (s != NULL) { /* Update existing client. */ crypto_uint64 unpacked_nonce = curvecpr_bytes_unpack_uint64(p->nonce); if (unpacked_nonce <= s->their_session_nonce) return -EINVAL; curvecpr_bytes_copy(nonce, "CurveCP-client-I", 16); curvecpr_bytes_copy(nonce + 16, p->nonce, 8); curvecpr_bytes_zero(data, 16); curvecpr_bytes_copy(data + 16, buf, num); if (crypto_box_open_afternm(data, data, num + 16, nonce, s->my_session_their_session_key)) return -EINVAL; s->their_session_nonce = unpacked_nonce; curvecpr_session_set_priv(s, priv); if (cf->ops.recv(server, s, data + sizeof(struct curvecpr_packet_initiate_box), num + 16 - sizeof(struct curvecpr_packet_initiate_box))) return -EINVAL; return 0; } else { struct curvecpr_session s_new, *s_new_stored; const struct curvecpr_packet_initiate_box *p_box; /* Register new client. */ curvecpr_bytes_copy(nonce, "minute-k", 8); curvecpr_bytes_copy(nonce + 8, p->cookie, 16); /* We can reuse data; the cookie will fit into it. */ curvecpr_bytes_zero(data, 16); curvecpr_bytes_copy(data + 16, p->cookie + 16, 80); /* Validate cookie. */ if (crypto_secretbox_open(data, data, 96, nonce, server->my_temporal_key)) { curvecpr_bytes_zero(data, 16); curvecpr_bytes_copy(data + 16, p->cookie + 16, 80); if (crypto_secretbox_open(data, data, 96, nonce, server->my_last_temporal_key)) return -EINVAL; } if (!curvecpr_bytes_equal(p->client_session_pk, data + 32, 32)) return -EINVAL; /* Cookie is valid; set up keys. */ curvecpr_session_new(&s_new); curvecpr_bytes_copy(s_new.their_session_pk, data + 32, 32); curvecpr_bytes_copy(s_new.my_session_sk, data + 64, 32); crypto_box_beforenm(s_new.my_session_their_session_key, s_new.their_session_pk, s_new.my_session_sk); curvecpr_bytes_copy(nonce, "CurveCP-client-I", 16); curvecpr_bytes_copy(nonce + 16, p->nonce, 8); curvecpr_bytes_zero(data, 16); curvecpr_bytes_copy(data + 16, buf, num); if (crypto_box_open_afternm(data, data, num + 16, nonce, s_new.my_session_their_session_key)) return -EINVAL; p_box = (struct curvecpr_packet_initiate_box *)data; /* Attempt to validate this client. */ { unsigned char vouch[64]; curvecpr_bytes_copy(s_new.their_global_pk, p_box->client_global_pk, 32); crypto_box_beforenm(s_new.my_global_their_global_key, s_new.their_global_pk, cf->my_global_sk); curvecpr_bytes_copy(nonce, "CurveCPV", 8); curvecpr_bytes_copy(nonce + 8, p_box->nonce, 16); curvecpr_bytes_zero(vouch, 16); curvecpr_bytes_copy(vouch + 16, p_box->vouch, 48); if (crypto_box_afternm(vouch, vouch, 64, nonce, s_new.my_global_their_global_key)) return -EINVAL; if (!curvecpr_bytes_equal(vouch + 32, s_new.their_session_pk, 32)) return -EINVAL; } /* All good, we can go ahead and submit the client for registration. */ s_new.their_session_nonce = curvecpr_bytes_unpack_uint64(p->nonce); curvecpr_bytes_copy(s_new.my_domain_name, p_box->server_domain_name, 256); curvecpr_session_set_priv(&s_new, priv); if (cf->ops.put_session(server, &s_new, &s_new_stored)) return -EINVAL; /* This can fail for a variety of reasons that are up to the delegate to determine, but two typical ones will be too many connections or an invalid domain name. */ /* Now the session is registered; we can send the encapsulated message. */ if (cf->ops.recv(server, s_new_stored, data + sizeof(struct curvecpr_packet_initiate_box), num + 16 - sizeof(struct curvecpr_packet_initiate_box))) return -EINVAL; return 0; } }
static int _handle_hello (struct curvecpr_server *server, void *priv, const struct curvecpr_packet_hello *p) { const struct curvecpr_server_cf *cf = &server->cf; struct curvecpr_session s; /* Used only as a temporary store to make what we're doing more clear. */ unsigned char nonce[24]; unsigned char data[96] = { 0 }; /* Dummy initialization. */ curvecpr_session_new(&s); curvecpr_session_set_priv(&s, priv); /* Verify initial connection parameters. */ curvecpr_bytes_copy(s.their_session_pk, p->client_session_pk, 32); crypto_box_beforenm(s.my_global_their_session_key, s.their_session_pk, cf->my_global_sk); curvecpr_bytes_copy(nonce, "CurveCP-client-H", 16); curvecpr_bytes_copy(nonce + 16, p->nonce, 8); curvecpr_bytes_copy(data + 16, p->box, 80); if (crypto_box_open_afternm(data, data, 96, nonce, s.my_global_their_session_key)) return -EINVAL; /* Set up session keys. */ crypto_box_keypair(s.my_session_pk, s.my_session_sk); /* Prepare to send a cookie packet. */ { struct curvecpr_packet_cookie po; struct curvecpr_packet_cookie_box po_box; curvecpr_bytes_zero(po_box._, 32); curvecpr_bytes_copy(po_box.server_session_pk, s.my_session_pk, 32); /* Generate the cookie. */ curvecpr_bytes_zero(po_box.cookie, 32); curvecpr_bytes_copy(po_box.cookie + 32, s.their_session_pk, 32); curvecpr_bytes_copy(po_box.cookie + 64, s.my_session_sk, 32); /* Encrypt the cookie with our global nonce and temporary key. */ curvecpr_bytes_copy(nonce, "minute-k", 8); if (cf->ops.next_nonce(server, nonce + 8, 16)) return -EINVAL; crypto_secretbox(po_box.cookie, po_box.cookie, 96, nonce, server->my_temporal_key); curvecpr_bytes_copy(po_box.cookie, nonce + 8, 16); /* Now encrypt the whole box. */ curvecpr_bytes_copy(nonce, "CurveCPK", 8); crypto_box_afternm((unsigned char *)&po_box, (const unsigned char *)&po_box, sizeof(struct curvecpr_packet_cookie_box), nonce, s.my_global_their_session_key); /* Build the rest of the packet. */ curvecpr_bytes_copy(po.id, "RL3aNMXK", 8); curvecpr_bytes_copy(po.client_extension, p->client_extension, 16); curvecpr_bytes_copy(po.server_extension, cf->my_extension, 16); curvecpr_bytes_copy(po.nonce, nonce + 8, 16); curvecpr_bytes_copy(po.box, (const unsigned char *)&po_box + 16, 144); if (cf->ops.send(server, &s, (const unsigned char *)&po, sizeof(struct curvecpr_packet_cookie))) return -EINVAL; } return 0; }
int main(int argc,char **argv) { long long hellopackets; long long r; long long nextaction; signal(SIGPIPE,SIG_IGN); if (!argv[0]) die_usage(0); for (;;) { char *x; if (!argv[1]) break; if (argv[1][0] != '-') break; x = *++argv; if (x[0] == '-' && x[1] == 0) break; if (x[0] == '-' && x[1] == '-' && x[2] == 0) break; while (*++x) { if (*x == 'q') { flagverbose = 0; continue; } if (*x == 'Q') { flagverbose = 1; continue; } if (*x == 'v') { if (flagverbose == 2) flagverbose = 3; else flagverbose = 2; continue; } if (*x == 'c') { if (x[1]) { keydir = x + 1; break; } if (argv[1]) { keydir = *++argv; break; } } die_usage(0); } } if (!nameparse(servername,*++argv)) die_usage("sname must be at most 255 bytes, at most 63 bytes between dots"); if (!hexparse(serverlongtermpk,32,*++argv)) die_usage("pk must be exactly 64 hex characters"); if (!multiipparse(serverip,*++argv)) die_usage("ip must be a comma-separated series of IPv4 addresses"); if (!portparse(serverport,*++argv)) die_usage("port must be an integer between 0 and 65535"); if (!hexparse(serverextension,16,*++argv)) die_usage("ext must be exactly 32 hex characters"); if (!*++argv) die_usage("missing prog"); for (;;) { r = open_read("/dev/null"); if (r == -1) die_fatal("unable to open /dev/null",0,0); if (r > 9) { close(r); break; } } if (keydir) { fdwd = open_cwd(); if (fdwd == -1) die_fatal("unable to open current working directory",0,0); if (chdir(keydir) == -1) die_fatal("unable to change to directory",keydir,0); if (load("publickey",clientlongtermpk,sizeof clientlongtermpk) == -1) die_fatal("unable to read public key from",keydir,0); if (load(".expertsonly/secretkey",clientlongtermsk,sizeof clientlongtermsk) == -1) die_fatal("unable to read secret key from",keydir,0); } else { crypto_box_keypair(clientlongtermpk,clientlongtermsk); } crypto_box_keypair(clientshorttermpk,clientshorttermsk); clientshorttermnonce = randommod(281474976710656LL); crypto_box_beforenm(clientshortserverlong,serverlongtermpk,clientshorttermsk); crypto_box_beforenm(clientlongserverlong,serverlongtermpk,clientlongtermsk); udpfd = socket_udp(); if (udpfd == -1) die_fatal("unable to create socket",0,0); for (hellopackets = 0;hellopackets < NUMIP;++hellopackets) { recent = nanoseconds(); /* send a Hello packet: */ clientextension_init(); clientshorttermnonce_update(); byte_copy(nonce,16,"CurveCP-client-H"); uint64_pack(nonce + 16,clientshorttermnonce); byte_copy(packet,8,"QvnQ5XlH"); byte_copy(packet + 8,16,serverextension); byte_copy(packet + 24,16,clientextension); byte_copy(packet + 40,32,clientshorttermpk); byte_copy(packet + 72,64,allzero); byte_copy(packet + 136,8,nonce + 16); crypto_box_afternm(text,allzero,96,nonce,clientshortserverlong); byte_copy(packet + 144,80,text + 16); socket_send(udpfd,packet,224,serverip + 4 * hellopackets,serverport); nextaction = recent + hellowait[hellopackets] + randommod(hellowait[hellopackets]); for (;;) { long long timeout = nextaction - recent; if (timeout <= 0) break; p[0].fd = udpfd; p[0].events = POLLIN; if (poll(p,1,timeout / 1000000 + 1) < 0) p[0].revents = 0; do { /* try receiving a Cookie packet: */ if (!p[0].revents) break; r = socket_recv(udpfd,packet,sizeof packet,packetip,packetport); if (r != 200) break; if (!(byte_isequal(packetip,4,serverip + 4 * hellopackets) & byte_isequal(packetport,2,serverport) & byte_isequal(packet,8,"RL3aNMXK") & byte_isequal(packet + 8,16,clientextension) & byte_isequal(packet + 24,16,serverextension) )) break; byte_copy(nonce,8,"CurveCPK"); byte_copy(nonce + 8,16,packet + 40); byte_zero(text,16); byte_copy(text + 16,144,packet + 56); if (crypto_box_open_afternm(text,text,160,nonce,clientshortserverlong)) break; byte_copy(servershorttermpk,32,text + 32); byte_copy(servercookie,96,text + 64); byte_copy(serverip,4,serverip + 4 * hellopackets); goto receivedcookie; } while (0); recent = nanoseconds(); } } errno = ETIMEDOUT; die_fatal("no response from server",0,0); receivedcookie: crypto_box_beforenm(clientshortservershort,servershorttermpk,clientshorttermsk); byte_copy(nonce,8,"CurveCPV"); if (keydir) { if (safenonce(nonce + 8,0) == -1) die_fatal("nonce-generation disaster",0,0); } else { randombytes(nonce + 8,16); } byte_zero(text,32); byte_copy(text + 32,32,clientshorttermpk); crypto_box_afternm(text,text,64,nonce,clientlongserverlong); byte_copy(vouch,16,nonce + 8); byte_copy(vouch + 16,48,text + 16); /* server is responding, so start child: */ if (open_pipe(tochild) == -1) die_fatal("unable to create pipe",0,0); if (open_pipe(fromchild) == -1) die_fatal("unable to create pipe",0,0); child = fork(); if (child == -1) die_fatal("unable to fork",0,0); if (child == 0) { if (keydir) if (fchdir(fdwd) == -1) die_fatal("unable to chdir to original directory",0,0); close(8); if (dup(tochild[0]) != 8) die_fatal("unable to dup",0,0); close(9); if (dup(fromchild[1]) != 9) die_fatal("unable to dup",0,0); /* XXX: set up environment variables */ signal(SIGPIPE,SIG_DFL); execvp(*argv,argv); die_fatal("unable to run",*argv,0); } close(fromchild[1]); close(tochild[0]); for (;;) { p[0].fd = udpfd; p[0].events = POLLIN; p[1].fd = fromchild[0]; p[1].events = POLLIN; if (poll(p,2,-1) < 0) { p[0].revents = 0; p[1].revents = 0; } do { /* try receiving a Message packet: */ if (!p[0].revents) break; r = socket_recv(udpfd,packet,sizeof packet,packetip,packetport); if (r < 80) break; if (r > 1152) break; if (r & 15) break; packetnonce = uint64_unpack(packet + 40); if (flagreceivedmessage && packetnonce <= receivednonce) break; if (!(byte_isequal(packetip,4,serverip + 4 * hellopackets) & byte_isequal(packetport,2,serverport) & byte_isequal(packet,8,"RL3aNMXM") & byte_isequal(packet + 8,16,clientextension) & byte_isequal(packet + 24,16,serverextension) )) break; byte_copy(nonce,16,"CurveCP-server-M"); byte_copy(nonce + 16,8,packet + 40); byte_zero(text,16); byte_copy(text + 16,r - 48,packet + 48); if (crypto_box_open_afternm(text,text,r - 32,nonce,clientshortservershort)) break; if (!flagreceivedmessage) { flagreceivedmessage = 1; randombytes(clientlongtermpk,sizeof clientlongtermpk); randombytes(vouch,sizeof vouch); randombytes(servername,sizeof servername); randombytes(servercookie,sizeof servercookie); } receivednonce = packetnonce; text[31] = (r - 64) >> 4; /* child is responsible for reading all data immediately, so we won't block: */ if (writeall(tochild[1],text + 31,r - 63) == -1) goto done; } while (0); do { /* try receiving data from child: */ long long i; if (!p[1].revents) break; r = read(fromchild[0],childbuf,sizeof childbuf); if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break; if (r <= 0) goto done; childbuflen = r; for (i = 0;i < childbuflen;++i) { if (childmessagelen < 0) goto done; if (childmessagelen >= sizeof childmessage) goto done; childmessage[childmessagelen++] = childbuf[i]; if (childmessage[0] & 128) goto done; if (childmessagelen == 1 + 16 * (unsigned long long) childmessage[0]) { clientextension_init(); clientshorttermnonce_update(); uint64_pack(nonce + 16,clientshorttermnonce); if (flagreceivedmessage) { r = childmessagelen - 1; if (r < 16) goto done; if (r > 1088) goto done; byte_copy(nonce,16,"CurveCP-client-M"); byte_zero(text,32); byte_copy(text + 32,r,childmessage + 1); crypto_box_afternm(text,text,r + 32,nonce,clientshortservershort); byte_copy(packet,8,"QvnQ5XlM"); byte_copy(packet + 8,16,serverextension); byte_copy(packet + 24,16,clientextension); byte_copy(packet + 40,32,clientshorttermpk); byte_copy(packet + 72,8,nonce + 16); byte_copy(packet + 80,r + 16,text + 16); socket_send(udpfd,packet,r + 96,serverip,serverport); } else { r = childmessagelen - 1; if (r < 16) goto done; if (r > 640) goto done; byte_copy(nonce,16,"CurveCP-client-I"); byte_zero(text,32); byte_copy(text + 32,32,clientlongtermpk); byte_copy(text + 64,64,vouch); byte_copy(text + 128,256,servername); byte_copy(text + 384,r,childmessage + 1); crypto_box_afternm(text,text,r + 384,nonce,clientshortservershort); byte_copy(packet,8,"QvnQ5XlI"); byte_copy(packet + 8,16,serverextension); byte_copy(packet + 24,16,clientextension); byte_copy(packet + 40,32,clientshorttermpk); byte_copy(packet + 72,96,servercookie); byte_copy(packet + 168,8,nonce + 16); byte_copy(packet + 176,r + 368,text + 16); socket_send(udpfd,packet,r + 544,serverip,serverport); } childmessagelen = 0; } } } while (0); } done: do { r = waitpid(child,&childstatus,0); } while (r == -1 && errno == EINTR); if (!WIFEXITED(childstatus)) { errno = 0; die_fatal("process killed by signal",0,0); } return WEXITSTATUS(childstatus); }
int main(void) { unsigned char k[crypto_box_BEFORENMBYTES]; int i; int ret; ret = crypto_box(c, m, 163, nonce, bobpk, alicesk); assert(ret == 0); for (i = 16; i < 163; ++i) { printf(",0x%02x", (unsigned int)c[i]); if (i % 8 == 7) printf("\n"); } printf("\n"); ret = crypto_box(c, m, 163, nonce, small_order_p, alicesk); assert(ret == -1); memset(c, 0, sizeof c); ret = crypto_box_beforenm(k, bobpk, alicesk); assert(ret == 0); crypto_box_afternm(c, m, 163, nonce, k); for (i = 16; i < 163; ++i) { printf(",0x%02x", (unsigned int)c[i]); if (i % 8 == 7) printf("\n"); } printf("\n"); ret = crypto_box_beforenm(k, small_order_p, alicesk); assert(ret == -1); assert(crypto_box_seedbytes() > 0U); assert(crypto_box_publickeybytes() > 0U); assert(crypto_box_secretkeybytes() > 0U); assert(crypto_box_beforenmbytes() > 0U); assert(crypto_box_noncebytes() > 0U); assert(crypto_box_zerobytes() > 0U); assert(crypto_box_boxzerobytes() > 0U); assert(crypto_box_macbytes() > 0U); assert(strcmp(crypto_box_primitive(), "curve25519xsalsa20poly1305") == 0); assert(crypto_box_curve25519xsalsa20poly1305_seedbytes() == crypto_box_seedbytes()); assert(crypto_box_curve25519xsalsa20poly1305_publickeybytes() == crypto_box_publickeybytes()); assert(crypto_box_curve25519xsalsa20poly1305_secretkeybytes() == crypto_box_secretkeybytes()); assert(crypto_box_curve25519xsalsa20poly1305_beforenmbytes() == crypto_box_beforenmbytes()); assert(crypto_box_curve25519xsalsa20poly1305_noncebytes() == crypto_box_noncebytes()); assert(crypto_box_curve25519xsalsa20poly1305_zerobytes() == crypto_box_zerobytes()); assert(crypto_box_curve25519xsalsa20poly1305_boxzerobytes() == crypto_box_boxzerobytes()); assert(crypto_box_curve25519xsalsa20poly1305_macbytes() == crypto_box_macbytes()); return 0; }
void functional_crypto(UNUSED(void **state)) { unsigned char nonce[crypto_box_NONCEBYTES]; unsigned char initiatenonce[crypto_box_NONCEBYTES]; unsigned char hellopacket[192] = {0}; unsigned char initiatepacket[256] = {0}; unsigned char messagepacket[120]; unsigned char messagepacketout[120] = {0}; unsigned char allzeroboxed[96] = {0}; unsigned char initiatebox[160] = {0}; unsigned char pubkeybox[96] = {0}; unsigned char lengthbox[40] = {0}; uint64_t plaintextlen; uint64_t readlen; outputstream write; connect_to_db(); wrap_crypto_write = false; assert_int_equal(0, filesystem_load(".keys/server-long-term.pub", serverlongtermpk, sizeof serverlongtermpk)); cc.nonce = (uint64_t) randommod(281474976710656LL); if (!ISODD(cc.nonce)) { cc.nonce++; } cc.receivednonce = 0; cc.state = TUNNEL_INITIAL; memcpy(nonce, "splonebox-client", 16); uint64_pack(nonce + 16, cc.nonce); /* pack hello packet */ memcpy(hellopacket, "oqQN2kaH", 8); /* pack compressed nonce */ memcpy(hellopacket + 104, nonce + 16, 8); /* generate client ephemeral keys */ if (crypto_box_keypair(clientlongtermpk, clientlongtermsk) != 0) return; /* generate client ephemeral keys */ if (crypto_box_keypair(clientshorttermpk, clientshorttermsk) != 0) return; memcpy(hellopacket + 8, clientshorttermpk, 32); assert_int_equal(0, crypto_box(allzeroboxed, allzeroboxed, 96, nonce, serverlongtermpk, clientshorttermsk)); memcpy(hellopacket + 112, allzeroboxed + 16, 80); crypto_init(); /* positiv test */ assert_int_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write)); /* wrong identifier */ memcpy(hellopacket, "deadbeef", 8); assert_int_not_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write)); memcpy(hellopacket, "oqQN2kaH", 8); /* wrong nonce */ cc.receivednonce = cc.nonce + 1; assert_int_not_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write)); cc.receivednonce = 0; /* wrong pubkey */ memset(hellopacket + 8, '0', 32); assert_int_not_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write)); memcpy(hellopacket + 8, clientshorttermpk, 32); assert_int_equal(0, crypto_recv_hello_send_cookie(&cc, hellopacket, &write)); /* crypto_recv_initiate() test */ /* pack initiate packet */ memcpy(initiatepacket, "oqQN2kaI", 8); memcpy(initiatepacket + 8, cookie, 96); /* pack compressed nonce */ memcpy(initiatepacket + 104, nonce + 16, 8); memcpy(initiatebox + 32, clientlongtermpk, 32); randombytes(initiatebox + 64, 16); memcpy(initiatenonce, "splonePV", 8); memcpy(initiatenonce + 8, initiatebox + 64, 16); memcpy(pubkeybox + 32, clientshorttermpk, 32); memcpy(pubkeybox + 64, servershorttermpk, 32); assert_int_equal(0, crypto_box(pubkeybox, pubkeybox, 96, initiatenonce, serverlongtermpk, clientlongtermsk)); memcpy(initiatebox + 80, pubkeybox + 16, 80); assert_int_equal(0, crypto_box(initiatebox, initiatebox, 160, nonce, servershorttermpk, clientshorttermsk)); memcpy(initiatepacket + 112, initiatebox + 16, 144); /* without valid certificate */ assert_int_not_equal(0, crypto_recv_initiate(&cc, initiatepacket)); /* all plugins are allowed to connect */ db_authorized_set_whitelist_all(); assert_int_equal(0, crypto_recv_initiate(&cc, initiatepacket)); /* crypto_write() test */ assert_int_equal(0, crypto_write(&cc, (char*) allzeroboxed, sizeof(allzeroboxed), &write)); /* crypto_read() test */ /* pack message packet */ memcpy(messagepacket, "oqQN2kaM", 8); /* pack compressed nonce */ memcpy(nonce, "splonebox-client", 16); uint64_pack(nonce + 16, cc.nonce); memcpy(messagepacket + 8, nonce + 16, 8); uint64_pack(lengthbox + 32, 120); assert_int_equal(0, crypto_box(lengthbox, lengthbox, 40, nonce, servershorttermpk, clientshorttermsk)); memcpy(messagepacket + 16, lengthbox + 16, 24); uint64_pack(nonce + 16, cc.nonce + 2); memset(allzeroboxed, 0, 96); assert_int_equal(0, crypto_box_afternm(allzeroboxed, allzeroboxed, 96, nonce, cc.clientshortservershort)); memcpy(messagepacket + 40, allzeroboxed + 16, 80); assert_int_equal(0, crypto_verify_header(&cc, messagepacket, &readlen)); assert_int_equal(0, crypto_read(&cc, messagepacket, (char*)messagepacketout, readlen, &plaintextlen)); db_close(); }