int SL_Crypto_AES::encrypt(const unsigned char *input, unsigned int input_len, unsigned char *out, unsigned int out_len) { unsigned int endblock_len = input_len % block_size_; unsigned int need_len = endblock_len ? (input_len-endblock_len+block_size_+1) : (input_len+1); if (out_len < need_len) { return -1; } unsigned char *input_pos = (unsigned char *)input; unsigned char *out_pos = (out + 1); unsigned int block_count = input_len/block_size_; for (unsigned int i=0; i<block_count; ++i) { encrypt_block(input_pos, out_pos); input_pos += block_size_; out_pos += block_size_; } if (endblock_len > 0) { char endblock[SL_CRYPTO_BLOCK_SIZE_32] = {0}; memcpy(endblock, input_pos, endblock_len); out[0] = block_size_-endblock_len; encrypt_block((const unsigned char *)endblock, out_pos); } else { out[0] = 0; } return need_len; }
/* * Calculates the blowfish S and P boxes for encryption and decryption. */ static int bf_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { struct bf_ctx *ctx = crypto_tfm_ctx(tfm); u32 *P = ctx->p; u32 *S = ctx->s; short i, j, count; u32 data[2], temp; /* Copy the initialization s-boxes */ for (i = 0, count = 0; i < 256; i++) for (j = 0; j < 4; j++, count++) S[count] = bf_sbox[count]; /* Set the p-boxes */ for (i = 0; i < 16 + 2; i++) P[i] = bf_pbox[i]; /* Actual subkey generation */ for (j = 0, i = 0; i < 16 + 2; i++) { temp = (((u32)key[j] << 24) | ((u32)key[(j + 1) % keylen] << 16) | ((u32)key[(j + 2) % keylen] << 8) | ((u32)key[(j + 3) % keylen])); P[i] = P[i] ^ temp; j = (j + 4) % keylen; } data[0] = 0x00000000; data[1] = 0x00000000; for (i = 0; i < 16 + 2; i += 2) { encrypt_block((struct bf_ctx *)ctx, data, data); P[i] = data[0]; P[i + 1] = data[1]; } for (i = 0; i < 4; i++) { for (j = 0, count = i * 256; j < 256; j += 2, count += 2) { encrypt_block((struct bf_ctx *)ctx, data, data); S[count] = data[0]; S[count + 1] = data[1]; } } /* Bruce says not to bother with the weak key check. */ return 0; }
int blowfish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { struct bf_ctx *ctx = crypto_tfm_ctx(tfm); u32 *P = ctx->p; u32 *S = ctx->s; short i, j, count; u32 data[2], temp; for (i = 0, count = 0; i < 256; i++) for (j = 0; j < 4; j++, count++) S[count] = bf_sbox[count]; for (i = 0; i < 16 + 2; i++) P[i] = bf_pbox[i]; for (j = 0, i = 0; i < 16 + 2; i++) { temp = (((u32)key[j] << 24) | ((u32)key[(j + 1) % keylen] << 16) | ((u32)key[(j + 2) % keylen] << 8) | ((u32)key[(j + 3) % keylen])); P[i] = P[i] ^ temp; j = (j + 4) % keylen; } data[0] = 0x00000000; data[1] = 0x00000000; for (i = 0; i < 16 + 2; i += 2) { encrypt_block((struct bf_ctx *)ctx, data, data); P[i] = data[0]; P[i + 1] = data[1]; } for (i = 0; i < 4; i++) { for (j = 0, count = i * 256; j < 256; j += 2, count += 2) { encrypt_block((struct bf_ctx *)ctx, data, data); S[count] = data[0]; S[count + 1] = data[1]; } } return 0; }
int main(){ unsigned char m[64]; unsigned char t[64]; unsigned char k[32]; unsigned char c[64]; unsigned char n[64]; for(int i=0; i<64; i++){ m[i]=0; t[i]=0; c[i]=0; } for(int i=0; i<32; i++){ k[i]=0; } strcpy(m, "Test"); strcpy(t, "Try"); strcpy(k, "Me"); encrypt_block(c, m, k,t); for(int i=0; i<64; i++){ printf("%.2x", c[i]); } printf("\n"); decrypt_block(n, c, k, t); if(memcmp(n, m, 64)){ printf("Failure!\n"); } else { printf("Success!\n"); } return 0; }
int ctr_mode_final(ctr_ctx_t *ctx, crypto_data_t *out, int (*encrypt_block)(const void *, const uint8_t *, uint8_t *)) { uint8_t *lastp; uint8_t *p; int i; if (out->cd_length < ctx->ctr_remainder_len) return (CRYPTO_DATA_LEN_RANGE); encrypt_block(ctx->ctr_keysched, (uint8_t *)ctx->ctr_cb, (uint8_t *)ctx->ctr_tmp); lastp = (uint8_t *)ctx->ctr_tmp; p = (uint8_t *)ctx->ctr_remainder; for (i = 0; i < ctx->ctr_remainder_len; i++) { p[i] ^= lastp[i]; } (void) crypto_put_output_data(p, out, ctx->ctr_remainder_len); out->cd_offset += ctx->ctr_remainder_len; ctx->ctr_remainder_len = 0; return (CRYPTO_SUCCESS); }
int main() { std::random_device rd; std::default_random_engine g(rd()); std::uniform_int_distribution<> d(0, 15); // generate key and plaintext nibs ks; for (int i = 0; i < 12; ++i) ks[i] = d(g); nibs ps; for (int i = 0; i < 12; ++i) ps[i] = d(g); // encrypt plaintext to get ciphertext nibs cs = encrypt_block(ks, ps); std::ofstream outfile("bf.txt"); // print out key on first line for (auto &k : ks) outfile << +k << " "; outfile << std::endl; // print out plaintext-ciphertext pair for (auto &p : ps) outfile << +p << " "; for (auto &c : cs) outfile << +c << " "; outfile << std::endl; // construct integer representing key during key guessing long key_int = ks[0] << 24 | ks[1] << 20 | ks[2] << 16 | ks[3] << 12 | ks[4] << 8 | ks[5] << 4 | ks[6]; std::cout << "Integer representing key: " << key_int << std::endl; return 0; }
//generate a word to use as an IV from a 16-bit int - should be relatively random byte generate_IV_from_nonce(int nonce, byte* keys) { byte data = nonce; int i; for(i = 0; i < 7; i++) { if(i%2 == 0) data = encrypt_block(data, keys) >> 1; else data = encrypt_block(data, keys) << 1; }
void EncryptCBC::encrypt(const void* src, void* dst, size_t len) { assert(len % 16 == 0); for (unsigned int i = 0; i < len; i += 16) { encrypt_block((uint8_t*)src + i, (uint8_t*)dst + i); } }
static const char* selftest(void) { BLOWFISH_context c; byte plain[] = "BLOWFISH"; byte buffer[8]; static const byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; static const byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 }; static const byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 }; const char *r; bf_setkey( (void *) &c, (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 ); encrypt_block( (void *) &c, buffer, plain ); if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) ) return "Blowfish selftest failed (1)."; decrypt_block( (void *) &c, buffer, buffer ); if( memcmp( buffer, plain, 8 ) ) return "Blowfish selftest failed (2)."; bf_setkey( (void *) &c, key3, 8 ); encrypt_block( (void *) &c, buffer, plain3 ); if( memcmp( buffer, cipher3, 8 ) ) return "Blowfish selftest failed (3)."; decrypt_block( (void *) &c, buffer, buffer ); if( memcmp( buffer, plain3, 8 ) ) return "Blowfish selftest failed (4)."; if ( (r = selftest_cbc ()) ) return r; if ( (r = selftest_cfb ()) ) return r; if ( (r = selftest_ctr ()) ) return r; return NULL; }
void encrypt_buffer(char *t, int size) { int nb_blocks = size / BLOCK_SIZE; int remaining_size = size - nb_blocks * BLOCK_SIZE; int i; for(i = 0; i <= nb_blocks; ++i){ encrypt_block(&t[i * BLOCK_SIZE]); } encrypt_partial_block(&t[i * BLOCK_SIZE], remaining_size); }
static void bf_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) { const __be32 *in_blk = (const __be32 *)src; __be32 *const out_blk = (__be32 *)dst; u32 in32[2], out32[2]; in32[0] = be32_to_cpu(in_blk[0]); in32[1] = be32_to_cpu(in_blk[1]); encrypt_block(crypto_tfm_ctx(tfm), out32, in32); out_blk[0] = cpu_to_be32(out32[0]); out_blk[1] = cpu_to_be32(out32[1]); }
static void bf_encrypt(void *ctx, u8 *dst, const u8 *src) { const u32 *in_blk = (const u32 *)src; u32 *const out_blk = (u32 *)dst; u32 in32[2], out32[2]; in32[0] = be32_to_cpu(in_blk[0]); in32[1] = be32_to_cpu(in_blk[1]); encrypt_block(ctx, out32, in32); out_blk[0] = cpu_to_be32(out32[0]); out_blk[1] = cpu_to_be32(out32[1]); }
static krb5_error_code derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key inkey, krb5_data *outrnd, const krb5_data *in_constant) { size_t blocksize, keybytes, n; krb5_error_code ret; krb5_data block = empty_data(); blocksize = enc->block_size; keybytes = enc->keybytes; if (blocksize == 1) return KRB5_BAD_ENCTYPE; if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes) return KRB5_CRYPTO_INTERNAL; /* Allocate encryption data buffer. */ ret = alloc_data(&block, blocksize); if (ret) return ret; /* Initialize the input block. */ if (in_constant->length == blocksize) { memcpy(block.data, in_constant->data, blocksize); } else { krb5int_nfold(in_constant->length * 8, (unsigned char *) in_constant->data, blocksize * 8, (unsigned char *) block.data); } /* Loop encrypting the blocks until enough key bytes are generated. */ n = 0; while (n < keybytes) { ret = encrypt_block(enc, inkey, &block); if (ret) goto cleanup; if ((keybytes - n) <= blocksize) { memcpy(outrnd->data + n, block.data, (keybytes - n)); break; } memcpy(outrnd->data + n, block.data, blocksize); n += blocksize; } cleanup: zapfree(block.data, blocksize); return ret; }
/** * Interoperability test. * * data must point at an array of two driver structures. Data will be encrypted * with the first driver, and decrypted with the second. * * If the two drivers interoperate, the test passes. */ static void crypto_block_cross(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t **drivers, const apr_crypto_block_key_type_e type, const apr_crypto_block_key_mode_e mode, int doPad, const unsigned char *in, apr_size_t inlen, const char *description) { const apr_crypto_driver_t *driver1 = drivers[0]; const apr_crypto_driver_t *driver2 = drivers[1]; apr_crypto_t *f1 = NULL; apr_crypto_t *f2 = NULL; const apr_crypto_key_t *key1 = NULL; const apr_crypto_key_t *key2 = NULL; unsigned char *cipherText = NULL; apr_size_t cipherTextLen = 0; unsigned char *plainText = NULL; apr_size_t plainTextLen = 0; const unsigned char *iv = NULL; apr_size_t blockSize = 0; f1 = make(tc, pool, driver1); f2 = make(tc, pool, driver2); key1 = passphrase(tc, pool, driver1, f1, type, mode, doPad, description); key2 = passphrase(tc, pool, driver2, f2, type, mode, doPad, description); cipherText = encrypt_block(tc, pool, driver1, f1, key1, in, inlen, &cipherText, &cipherTextLen, &iv, &blockSize, description); plainText = decrypt_block(tc, pool, driver2, f2, key2, cipherText, cipherTextLen, &plainText, &plainTextLen, iv, &blockSize, description); if (cipherText && plainText) { if (memcmp(in, plainText, inlen)) { fprintf(stderr, "cross mismatch: %s %s/%s\n", description, apr_crypto_driver_name(driver1), apr_crypto_driver_name( driver2)); } ABTS_STR_EQUAL(tc, (char *)in, (char *)plainText); } }
int ctr_mode_final(ctr_ctx_t *ctx, crypto_data_t *out, int (*encrypt_block)(const void *, const uint8_t *, uint8_t *)) { uint8_t *lastp; void *iov_or_mp; offset_t offset; uint8_t *out_data_1; uint8_t *out_data_2; size_t out_data_1_len; uint8_t *p; int i; if (out->cd_length < ctx->ctr_remainder_len) return (CRYPTO_DATA_LEN_RANGE); encrypt_block(ctx->ctr_keysched, (uint8_t *)ctx->ctr_cb, (uint8_t *)ctx->ctr_tmp); lastp = (uint8_t *)ctx->ctr_tmp; p = (uint8_t *)ctx->ctr_remainder; for (i = 0; i < ctx->ctr_remainder_len; i++) { p[i] ^= lastp[i]; } crypto_init_ptrs(out, &iov_or_mp, &offset); crypto_get_ptrs(out, &iov_or_mp, &offset, &out_data_1, &out_data_1_len, &out_data_2, ctx->ctr_remainder_len); bcopy(p, out_data_1, out_data_1_len); if (out_data_2 != NULL) { bcopy((uint8_t *)p + out_data_1_len, out_data_2, ctx->ctr_remainder_len - out_data_1_len); } out->cd_offset += ctx->ctr_remainder_len; ctx->ctr_remainder_len = 0; return (CRYPTO_SUCCESS); }
void encrypt_final(struct poet_ctx *ctx, const uint8_t *plaintext, uint64_t plen, uint8_t *ciphertext, uint8_t tag[BLOCKLEN]) { #ifdef DEBUG int i; #endif uint64_t offset=0; uint64_t len; block s; block tmp; block tmp2; while( plen > BLOCKLEN ) { encrypt_block(ctx, (plaintext+offset), (ciphertext+offset)); plen -= BLOCKLEN; offset += BLOCKLEN; } /* Encrypt length of message */ ctx->mlen+=(plen*8); memset(s,0,BLOCKLEN); len = TO_LITTLE_ENDIAN_64(ctx->mlen); memcpy(s, &len,8); AES_encrypt(s, s ,&(ctx->aes_enc)); /* Last message block must be padded if necesscary */ memcpy(tmp,plaintext+offset,plen); memcpy(tmp+plen,ctx->tau,BLOCKLEN-plen); /* Process last block + tag generation */ TOP_HASH; xor_block(tmp,s,tmp); xor_block(ctx->x,tmp,ctx->x); AES_encrypt(ctx->x, tmp, &(ctx->aes_enc)); BOTTOM_HASH; xor_block(tmp2, tmp,ctx->y); memcpy(ctx->y, tmp, BLOCKLEN); xor_block(tmp,s,tmp2); #ifdef DEBUG puts("S"); for(i=0;i<16;i++) printf("%02x ",s[i]); puts(""); puts("X"); for(i=0;i<16;i++) printf("%02x ",ctx->x[i]); puts(""); puts("Y"); for(i=0;i<16;i++) printf("%02x ",ctx->y[i]); puts(""); #endif /* Do tag splitting if needed */ memcpy(ciphertext+offset,tmp,plen); memcpy(tag,tmp+plen,BLOCKLEN-plen); /* Generate tag */ TOP_HASH; xor_block(ctx->x, ctx->tau, ctx->x); xor_block(ctx->x, ctx->tm, ctx->x); AES_encrypt(ctx->x, tmp, &(ctx->aes_enc)); BOTTOM_HASH; xor_block(tmp, ctx->y, tmp); xor_block(tmp, ctx->tm, tmp); memcpy(tag+(BLOCKLEN-plen),tmp,plen); }
static void brng_hmac(byte *Sigma, byte *S, byte *to, uint32 size){ uint32* sigma = (uint32*)Sigma; uint32 act_sz = ((size - 1) / 16 + 1) * 4; uint32 *X = new uint32[act_sz]; uint32 *Y = new uint32[act_sz]; uint32 byteSZ = act_sz << 2; memset(X, 0x00, sizeof X); for (size_t jj = 0; jj < act_sz; ++jj) X[jj] ^= X[jj]; memcpy(X, S, size); for (size_t i = 0; i < byteSZ; i += 4) { byte*l = ((byte*)X) + i, *r = ((byte*)X) + 3 + i; *r ^= *l, *l ^= *r, *r ^= *l; l = ((byte*)X) + i + 1, r = ((byte*)X) + 2 + i; *r ^= *l, *l ^= *r, *r ^= *l; } for (size_t i = 0; i < 32; i += 4) { byte*l = ((byte*)sigma) + i, *r = ((byte*)sigma) + 3 + i; *r ^= *l, *l ^= *r, *r ^= *l; l = ((byte*)sigma) + i + 1, r = ((byte*)sigma) + 2 + i; *r ^= *l, *l ^= *r, *r ^= *l; } uint32 s[4], r[4]; memset(s, 0, sizeof s); encrypt_block(s, r, sigma); for (size_t i = 0; i < act_sz - 4; i += 4) { for (size_t j = 0; j < 4; ++j) X[i + j] ^= s[j]; encrypt_block(X + i, s, sigma); } uint32 diff = byteSZ - size; if (!diff) { phi1(r); for (size_t i = 0; i < 4; ++i) s[i] ^= r[i] ^ X[act_sz - 4 + i]; } else { psi(X + act_sz - 4,16- diff); phi2(r); for (size_t i = 0; i < 4; ++i) s[i] ^= r[i] ^ X[act_sz - 4 + i]; } encrypt_block(s, r, sigma); for (size_t jj = 0; jj < 4; ++jj) change_endian((byte*)(r + jj)); memcpy(to, r, 8); for (size_t i = 0; i < 32; i += 4) { byte*l = ((byte*)sigma) + i, *r = ((byte*)sigma) + 3 + i; *r ^= *l, *l ^= *r, *r ^= *l; l = ((byte*)sigma) + i + 1, r = ((byte*)sigma) + 2 + i; *r ^= *l, *l ^= *r, *r ^= *l; } delete X; delete Y; }
/** * Send a KEYINFO message. Sent during the Announce phase for a group * with encryption enabled. * Returns 1 on success, 0 on fail. */ int send_keyinfo(const struct finfo_t *finfo, int attempt) { unsigned char *buf, *iv; struct uftp_h *header; struct keyinfo_h *keyinfo; struct destkey *keylist; unsigned int hsize, payloadlen, len; int maxdest, packetcnt, dests, iv_init, i; int unauth_keytype, unauth_keylen, unauth_ivlen; // Don't use a cipher in an authentication mode to encrypt the group master unauth_keytype = unauth_key(keytype); get_key_info(unauth_keytype, &unauth_keylen, &unauth_ivlen); buf = safe_calloc(MAXMTU, 1); iv = safe_calloc(unauth_ivlen, 1); header = (struct uftp_h *)buf; keyinfo = (struct keyinfo_h *)(buf + sizeof(struct uftp_h)); keylist = (struct destkey *)((char *)keyinfo + sizeof(struct keyinfo_h)); set_uftp_header(header, KEYINFO, finfo->group_id, finfo->group_inst, grtt, destcount); keyinfo->func = KEYINFO; keyinfo->hlen = sizeof(struct keyinfo_h) / 4; keylist = (struct destkey *)((uint8_t *)keyinfo + (keyinfo->hlen * 4)); iv_init = 0; hsize = sizeof(struct keyinfo_h); maxdest = blocksize / sizeof(struct destkey); packetcnt = 1; for (i = 0, dests = 0; i < destcount; i++) { if (destlist[i].status == DEST_REGISTERED) { if (!iv_init) { ivctr++; keyinfo->iv_ctr_hi =htonl((ivctr & 0xFFFFFFFF00000000LL) >> 32); keyinfo->iv_ctr_lo = htonl(ivctr & 0x00000000FFFFFFFFLL); iv_init = 1; } keylist[dests].dest_id = destlist[i].id; build_iv(iv, destlist[i].encinfo->salt, unauth_ivlen, uftp_htonll(ivctr), header->src_id); if (!encrypt_block(unauth_keytype, iv,destlist[i].encinfo->key, NULL,0, &groupmaster[1], sizeof(groupmaster) - 1, keylist[dests].groupmaster, &len)) { glog0(finfo, "Error encrypting KEYINFO for %s", destlist[i].name); free(buf); free(iv); return 0; } dests++; } if ((dests >= maxdest) || ((i == destcount - 1) && (dests > 0))) { header->seq = htons(send_seq++); payloadlen = hsize + (dests * sizeof(struct destkey)); glog2(finfo, "Sending KEYINFO %d.%d", attempt, packetcnt); if (nb_sendto(sock, buf, payloadlen + sizeof(struct uftp_h), 0, (struct sockaddr *)&receive_dest, family_len(receive_dest)) == SOCKET_ERROR) { gsockerror(finfo, "Error sending KEYINFO"); sleep(1); free(buf); free(iv); return 0; } if (packet_wait) usleep(packet_wait); memset(keylist, 0, maxdest * sizeof(struct destkey)); iv_init = 0; dests = 0; packetcnt++; } }
int main(int argc, char *argv[]) { int nonce_flag = 0; int nonce; int i; int length = atoi(argv[1]); char* key_string = argv[3]; if (argc > 4) { nonce = atoi(argv[4]); nonce_flag = 1; } int num_blocks = ceil( (double)length / 8.0); int pad = length - (length/8)*8; byte key1 = convert_char_to_hex(key_string[0]); byte key2 = convert_char_to_hex(key_string[1]); byte key = (key1 << 4) + key2; byte* keys = generate_round_keys(key); printf("Pad:\t\t%d\n", pad); printf("#Blocks:\t%d\n", num_blocks); printf("Key:\t\t0x%02X\n", key); byte IV; if(nonce_flag) { IV = generate_IV_from_nonce(nonce, keys); printf("Nonce:\t\t%d\n", nonce); } else IV = 0xA5; printf("IV:\t\t0x%02X\n", IV); byte* CTR = (byte*)malloc(num_blocks*sizeof(byte)); for(i = 0; i < num_blocks; i++) { CTR[i] = generate_IV_from_nonce( IV++, keys); //printf("CTR%d:\t\t0x%02X\n", i,CTR[i]); } char** bitstream = (char**)malloc(num_blocks*sizeof(char*)); for(i = 0; i < num_blocks; i++) { byte out = encrypt_block(CTR[i], keys); bitstream[i] = byte_to_bit_string(out); } if(pad > 0) bitstream[num_blocks-1][8-pad] = '\0'; char * outfile = argv[2]; FILE * ofp = fopen(outfile, "w"); if(ofp == NULL) { printf("Cannot open output file. Exiting...\n"); exit(1); } else { for(i = 0; i < num_blocks; i++) fprintf(ofp, "%s\n", bitstream[i]); } fprintf(ofp,"\n"); fclose(ofp); }
/** * Sends a KEYINFO to each client that the server sent a REG_CONF for. */ void send_keyinfo(struct pr_group_list_t *group, const uint32_t *addrlist, int addrlen) { unsigned char *buf, *iv; struct uftp_h *header; struct keyinfo_h *keyinfo_hdr; struct destkey *keylist; unsigned int payloadlen, len; int maxdest, packetcnt, dests, iv_init, foundaddr, i, j; int unauth_keytype, unauth_keylen, unauth_ivlen; struct pr_destinfo_t *dest; // Don't use a cipher in an authentication mode to encrypt the group master unauth_keytype = unauth_key(group->keytype); get_key_info(unauth_keytype, &unauth_keylen, &unauth_ivlen); buf = safe_calloc(MAXMTU, 1); iv = safe_calloc(unauth_ivlen, 1); header = (struct uftp_h *)buf; keyinfo_hdr = (struct keyinfo_h *)(buf + sizeof(struct uftp_h)); keylist= (struct destkey *)((char *)keyinfo_hdr + sizeof(struct keyinfo_h)); set_uftp_header(header, KEYINFO, group); keyinfo_hdr->func = KEYINFO; keyinfo_hdr->hlen = sizeof(struct keyinfo_h) / 4; iv_init = 0; maxdest = max_msg_dest(group, KEYINFO, keyinfo_hdr->hlen * 4); packetcnt = 1; for (i = 0, dests = 0; i < group->destcount; i++) { dest = &group->destinfo[i]; if (dest->state == PR_CLIENT_CONF) { if (addrlist) { // We just got a REG_CONF, so only send to listed hosts for (j = 0, foundaddr = 0; (j < addrlen) && (!foundaddr); j++) { if (dest->id == addrlist[j]) { foundaddr = 1; } } } else { foundaddr = 1; } if (foundaddr) { if (!iv_init) { group->ivctr++; keyinfo_hdr->iv_ctr_hi = htonl((group->ivctr & 0xFFFFFFFF00000000LL) >> 32); keyinfo_hdr->iv_ctr_lo = htonl(group->ivctr & 0x00000000FFFFFFFFLL); iv_init = 1; } keylist[dests].dest_id = dest->id; build_iv(iv, dest->salt, unauth_ivlen, uftp_htonll(group->ivctr), group->src_id); if (!encrypt_block(unauth_keytype, iv, dest->key, NULL, 0, &group->groupmaster[1], sizeof(group->groupmaster) - 1, keylist[dests].groupmaster, &len)) { glog0(group, "Error encrypting KEYINFO for %s", dest->name); free(buf); free(iv); return; } dests++; } } if ((dests >= maxdest) || ((i == group->destcount - 1) && (dests > 0))) { payloadlen = sizeof(struct keyinfo_h) + (dests * sizeof(struct destkey)); glog2(group,"Sending KEYINFO %d.%d", group->keyinfo_cnt, packetcnt); if (nb_sendto(listener, buf, payloadlen + sizeof(struct uftp_h), 0, (struct sockaddr *)&group->privatemcast, family_len(group->privatemcast)) == SOCKET_ERROR) { gsockerror(group, "Error sending KEYINFO"); free(buf); free(iv); return; } // TODO: This value is good for around 100Mbps. This is under the // assumption that the client proxy is local to the clients // it serves. This should probably be a parameter. usleep(120); memset(keylist, 0, maxdest * sizeof(struct destkey)); iv_init = 0; dests = 0; packetcnt++; } }
int s3fs::Crypto::pwriteAES(int fd, const char *buf, size_t buflen, off_t offset) { char readBlock[AES_BLOCK_SIZE]; unsigned char writeBlock[AES_BLOCK_SIZE]; unsigned char buffer[AES_BLOCK_SIZE]; size_t offsetIndex = offset % AES_BLOCK_SIZE; size_t readOffset = offset - offsetIndex; size_t writeOffset = readOffset; size_t bufIndex = 0; bool newfile = false; int bytesRead = 0; int bytesWritten = 0; int enclen = 0; struct stat st; memset(readBlock, 0, AES_BLOCK_SIZE); memset(writeBlock, 0, AES_BLOCK_SIZE); memset(buffer, 0, AES_BLOCK_SIZE); do { if(!newfile) { if(fstatAES(fd, &st) != 0) return 1; bytesRead = preadAES(fd, readBlock, AES_BLOCK_SIZE, readOffset); if(bytesRead <= 0) { newfile = true; continue; } memcpy(buffer, readBlock, bytesRead); //Fill the buffer with contents from the readBlock if(bufIndex <= 0) { memcpy((buffer + offsetIndex), (buf + bufIndex), (AES_BLOCK_SIZE - offsetIndex)); enclen += (bytesRead + ((buflen - bufIndex) >= AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : (buflen - bufIndex)); bufIndex += (AES_BLOCK_SIZE - offsetIndex); } else { memcpy(buffer, (buf + bufIndex), ((buflen - bufIndex) >= AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : (buflen - bufIndex)); enclen += ((buflen - bufIndex) >= AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : (buflen - bufIndex); bufIndex += ((buflen - bufIndex) >= AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : (buflen - bufIndex); } //Set padding if needed if(enclen < AES_BLOCK_SIZE && ((st.st_size - buflen) < AES_BLOCK_SIZE)) { set_padding(buffer, enclen); int padlen = get_padding(buffer); // FGPRINT("s3fs::Crypto Encrypted padding length %d\n", padlen); } else if (enclen == AES_BLOCK_SIZE && bufIndex == buflen) { encrypt_block(buffer, AES_BLOCK_SIZE, writeBlock); bytesWritten = pwrite(fd, &writeBlock, AES_BLOCK_SIZE, writeOffset); memset(buffer, 0, AES_BLOCK_SIZE); set_padding(buffer, 0); int padlen = get_padding(buffer); // FGPRINT("s3fs::Crypto Encrypted padding length %d\n", padlen); } encrypt_block(buffer, AES_BLOCK_SIZE, writeBlock); bytesWritten = pwrite(fd, &writeBlock, AES_BLOCK_SIZE, writeOffset); writeOffset += bytesWritten; readOffset += bytesRead; } else { memset(buffer, 0, AES_BLOCK_SIZE); memcpy(buffer, (buf + bufIndex), ((buflen - bufIndex) >= AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : (buflen - bufIndex)); enclen += ((buflen - bufIndex) >= AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : (buflen - bufIndex); bufIndex += ((buflen - bufIndex) >= AES_BLOCK_SIZE) ? AES_BLOCK_SIZE : (buflen - bufIndex); if(enclen < AES_BLOCK_SIZE) { set_padding(buffer, enclen); int padlen = get_padding(buffer); // FGPRINT("s3fs::Crypto Encrypted padding length %d\n", padlen); } else if (enclen == AES_BLOCK_SIZE && bufIndex == buflen) { encrypt_block(buffer, AES_BLOCK_SIZE, writeBlock); bytesWritten = pwrite(fd, &writeBlock, AES_BLOCK_SIZE, writeOffset); writeOffset += bytesWritten; memset(buffer, 0, AES_BLOCK_SIZE); set_padding(buffer, 0); int padlen = get_padding(buffer); // FGPRINT("s3fs::Crypto Encrypted padding length %d\n", padlen); } encrypt_block(buffer, AES_BLOCK_SIZE, writeBlock); bytesWritten = pwrite(fd, &writeBlock, AES_BLOCK_SIZE, writeOffset); writeOffset += bytesWritten; } memset(readBlock, 0, AES_BLOCK_SIZE); memset(writeBlock, 0, AES_BLOCK_SIZE); memset(buffer, 0, AES_BLOCK_SIZE); enclen = 0; } while(bufIndex < buflen); return bufIndex; }