00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "vsl_api.h"
00015 #include "vsl_util.h"
00016 #include "vsl.h"
00017 #include "../poly1305aes/aes.h"
00018 #include "../poly1305aes/poly1305aes.h"
00019 #include <openssl/md5.h>
00020 #include <openssl/sha.h>
00021 #include <sys/param.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <fcntl.h>
00025
00026
00027
00028
00029
00030
00031
00032
00033 int gen_key (unsigned char* key) {
00034 int fd;
00035 if ( (fd = open(RANDDEV, 0)) < 0)
00036 LOGFAIL(VSL_ERRNO, "cannot open %s for reading: %s!\n",
00037 RANDDEV, strerror(errno));
00038 int ret;
00039 if ( (ret=read(fd, (void*)key, VSL_KEYLEN)) != VSL_KEYLEN) {
00040 close(fd);
00041 if (ret < 0)
00042 LOGFAIL(VSL_ERRNO, "cannot read from %s: %s!\n",
00043 RANDDEV, strerror(errno));
00044 else
00045 LOGFATAL("cannot read enough random bytes!");
00046 }
00047
00048 if ( close(fd) != 0)
00049 LOGFAIL(VSL_ERRNO, "cannot close %s: %s!\n",
00050 RANDDEV, strerror(errno));
00051 return(0);
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 void init_keys_c(vsl_sock* sock, const unsigned char* key) {
00064 LOG("Initializing client keys...");
00065 md5(key, VSL_ENC_KEYLEN, (unsigned char*) "SRVENC", 7, sock->enc_recv_key);
00066 md5(key, VSL_ENC_KEYLEN, (unsigned char*) "CLTENC", 7, sock->enc_send_key);
00067 sha256(key, VSL_AUTH_KEYLEN, (unsigned char*) "SRVAUT", 7, sock->auth_recv_key);
00068 sha256(key, VSL_AUTH_KEYLEN, (unsigned char*) "CLTAUT", 7, sock->auth_send_key);
00069 poly1305aes_clamp(sock->auth_send_key);
00070 poly1305aes_clamp(sock->auth_recv_key);
00071 LOG("enc send key is " KEY_STR ".", KEY_VEC(sock->enc_send_key));
00072 LOG("enc recv key is " KEY_STR ".", KEY_VEC(sock->enc_recv_key));
00073 LOG("auth send key is " KEY_STR ".", KEY_VEC(sock->auth_send_key));
00074 LOG("auth recv key is " KEY_STR ".", KEY_VEC(sock->auth_recv_key));
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 void init_keys_s(vsl_sock* sock, const unsigned char* key) {
00088 LOG("Initializing server keys...");
00089 md5(key, VSL_ENC_KEYLEN, (unsigned char*) "SRVENC", 7, sock->enc_send_key);
00090 md5(key, VSL_ENC_KEYLEN, (unsigned char*) "CLTENC", 7, sock->enc_recv_key);
00091 sha256(key, VSL_AUTH_KEYLEN, (unsigned char*) "SRVAUT", 7, sock->auth_send_key);
00092 sha256(key, VSL_AUTH_KEYLEN, (unsigned char*) "CLTAUT", 7, sock->auth_recv_key);
00093 poly1305aes_clamp(sock->auth_send_key);
00094 poly1305aes_clamp(sock->auth_recv_key);
00095 LOG("enc send key is " KEY_STR ".", KEY_VEC(sock->enc_send_key));
00096 LOG("enc recv key is " KEY_STR ".", KEY_VEC(sock->enc_recv_key));
00097 LOG("auth send key is " KEY_STR ".", KEY_VEC(sock->auth_send_key));
00098 LOG("auth recv key is " KEY_STR ".", KEY_VEC(sock->auth_recv_key));
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 void md5(const unsigned char* s1, int l1,
00113 const unsigned char* s2, int l2, unsigned char *hash) {
00114 unsigned char s[l1+l2];
00115 memcpy((void*)s, (void*) s1, l1);
00116 memcpy((void*)s + l1, (void*) s2, l2);
00117 MD5(s, l1+l2, hash);
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void sha256(const unsigned char* s1, int l1,
00130 const unsigned char* s2, int l2, unsigned char *hash) {
00131 unsigned char s[l1+l2];
00132 memcpy((void*)s, (void*) s1, l1);
00133 memcpy((void*)s + l1, (void*) s2, l2);
00134 SHA256(s, l1+l2, hash);
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144 bool is_blocking (vsl_sock* socket) {
00145 int nonblocking = 0;
00146 int len = sizeof(int);
00147 int ret;
00148 if ( (ret=vfer_getsockopt(socket->vfd, VFERSO_NONBLOCK,
00149 &nonblocking, &len)) != 0)
00150 LOGFATAL("can't get socket state: %s", vfer_errortext(ret));
00151 return(nonblocking == 0);
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161 void set_blocking (vsl_sock* socket, bool mode) {
00162 int val;
00163 int ret;
00164 if (mode)
00165 val = 0;
00166 else
00167 val = 1;
00168 if ( (ret = vfer_setsockopt(socket->vfd, VFERSO_NONBLOCK,
00169 (void*) &val, sizeof(val))) != 0)
00170 LOGFATAL("can't set socket state: %s!", vfer_errortext(ret));
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 unsigned char* write_objs(size_t* total, ... ) {
00199 void *obj;
00200 unsigned char *buf, *start;
00201 size_t len;
00202
00203 va_list ap1;
00204 va_list ap2;
00205
00206 va_start(ap1, total);
00207 va_copy(ap2, ap1);
00208
00209
00210 len = 0;
00211 while ( va_arg(ap1, void*) != NULL )
00212 len += va_arg(ap1, size_t);
00213 va_end(ap1);
00214
00215
00216 if ( (start = malloc(len)) == NULL)
00217 return NULL;
00218 buf = start;
00219 *total = len;
00220
00221
00222 while ( (obj = va_arg(ap2, void*)) != NULL ) {
00223 len = va_arg(ap2, size_t);
00224 memcpy(buf, obj, len);
00225 buf += len;
00226 }
00227
00228 va_end(ap2);
00229 return(start);
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 unsigned char* read_objs(unsigned char* src, size_t max, ... ) {
00260 void *buf;
00261 size_t len;
00262 va_list ap;
00263
00264 va_start(ap, max);
00265
00266
00267 while ( (buf = va_arg(ap, void*)) != NULL ) {
00268 len = va_arg(ap, size_t);
00269 max -= len;
00270 if (max < 0) {
00271
00272 while ( va_arg(ap, void*) != NULL )
00273 (void) va_arg(ap, size_t);
00274 va_end(ap);
00275 return NULL;
00276 }
00277 memcpy(buf, src, len);
00278 src += len;
00279 }
00280
00281 va_end(ap);
00282 return(src);
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 #if __BYTE_ORDER == __BIG_ENDIAN || BYTE_ORDER == BIG_ENDIAN
00294 inline uint64_t htonll(uint64_t val) {
00295 return val;
00296 }
00297 #elif __BYTE_ORDER == __LITTLE_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN
00298 inline uint64_t htonll(uint64_t val) {
00299 uint32_t high = (uint32_t) (val >> 32);
00300 uint32_t low = (uint32_t) val;
00301 return ( (uint64_t) htonl(high) + ((uint64_t) htonl(low) << 32));
00302 }
00303 #else
00304 #error "Can't detect byte order"
00305 #endif
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 #if __BYTE_ORDER == __BIG_ENDIAN || BYTE_ORDER == BIG_ENDIAN
00316 inline uint64_t ntohll(uint64_t val) {
00317 return val;
00318 }
00319 #elif __BYTE_ORDER == __LITTLE_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN
00320 inline uint64_t ntohll(uint64_t val) {
00321 uint32_t high = (uint32_t) (val >> 32);
00322 uint32_t low = (uint32_t) val;
00323 return ( (uint64_t) ntohl(high) + ((uint64_t) ntohl(low) << 32));
00324 }
00325 #else
00326 #error "Can't detect byte order"
00327 #endif
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 void aes_ctr (unsigned char* ctr,
00345 const unsigned char* key,
00346 unsigned char* buf,
00347 const size_t len) {
00348 int blocks = len / 16;
00349 int bytes = len % 16;
00350
00351 int i;
00352 unsigned char c[16];
00353 for (i=1; i <= blocks; i++) {
00354 aes(c, key, ctr);
00355 xor16(buf, c);
00356 ctr_inc(ctr);
00357 buf += 16;
00358 }
00359
00360
00361 if (bytes != 0) {
00362 unsigned char b[16];
00363 aes(c, key, ctr);
00364 memcpy( (void*)b, (void*)buf, bytes);
00365 xor16(b, c);
00366 memcpy( (void*)buf, (void*)b, bytes);
00367 }
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377 inline void ctr_inc (unsigned char* ctr) {
00378 int i;
00379 for (i=15; i > 7; i--)
00380 if ( ctr[i] == 255 )
00381 ctr[i] = 0;
00382 else {
00383 ctr[i]++;
00384 break;
00385 }
00386 if ( i == 7 )
00387 LOGFATAL("counter overflow!");
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 inline void xor16 (unsigned char* b1, unsigned char* b2) {
00399
00400 int i;
00401 for (i=0; i<16; i++)
00402 b1[i] ^= b2[i];
00403
00404
00405
00406
00407
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 int transfer ( vsl_sock *sock, transmit_fn fn,
00430 unsigned char* buf, size_t min, size_t len) {
00431
00432
00433 if ( !is_blocking(sock) &&
00434 vfer_is_stream(sock->vfd) )
00435 LOGFATAL("nonblocking IO not supported for streamed connections!");
00436
00437 ssize_t processed = 0;
00438 size_t remainder = len;
00439 do {
00440 LOG("trying to process %zd bytes...", remainder);
00441 if ( (processed = (*fn)(sock->vfd, buf, remainder)) < 0 ) {
00442 if ( processed == VFER_WOULDBLOCK ||
00443 processed == VFER_INVAL ||
00444 processed == VFER_UNCONN)
00445 LOGFAIL(processed, "transmit function returned %s", vfer_errortext(processed));
00446 else
00447 LOGFATAL("processing failed: %s", vfer_errortext(processed));
00448 }
00449 else if (processed != remainder) {
00450 if ( vfer_is_stream(sock->vfd) ) {
00451 LOG("processed %zd bytes, trying more..", processed);
00452 buf += processed;
00453 remainder -= processed;
00454 continue;
00455 }
00456 else if (processed >= min)
00457 LOGFAIL(len - remainder, "processed %zd bytes, returning.", len - remainder);
00458 else
00459 LOGFATAL("fn processed %zd instead of %zd bytes!", processed, len);
00460 }
00461 break;
00462 } while(1);
00463 LOGFAIL(len, "processed %zd bytes, returning.", len);
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473