static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; const size_t key_len = EVP_PKEY_size(ctx->pkey); if (!out) { *outlen = key_len; return 1; } if (*outlen < key_len) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_encrypt, EVP_R_BUFFER_TOO_SMALL); return 0; } if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { if (!setup_tbuf(rctx, ctx) || !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen, rctx->oaep_label, rctx->oaep_labellen, rctx->md, rctx->mgf1md) || !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len, RSA_NO_PADDING)) { return 0; } return 1; } return RSA_encrypt(rsa, outlen, out, *outlen, in, inlen, rctx->pad_mode); }
/* * Send a client key exchange message. */ static int ICACHE_FLASH_ATTR send_client_key_xchg(SSL *ssl) { uint8_t *buf = ssl->bm_data; uint8_t premaster_secret[SSL_SECRET_SIZE]; int enc_secret_size = -1; buf[0] = HS_CLIENT_KEY_XCHG; buf[1] = 0; premaster_secret[0] = 0x03; /* encode the version number */ premaster_secret[1] = SSL_PROTOCOL_MINOR_VERSION; /* must be TLS 1.1 */ if (get_random(SSL_SECRET_SIZE-2, &premaster_secret[2]) < 0) return SSL_NOT_OK; //DISPLAY_RSA(ssl, ssl->x509_ctx->rsa_ctx); /* rsa_ctx->bi_ctx is not thread-safe */ SSL_CTX_LOCK(ssl->ssl_ctx->mutex); enc_secret_size = RSA_encrypt(ssl->x509_ctx->rsa_ctx, premaster_secret, SSL_SECRET_SIZE, &buf[6], 0); SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); buf[2] = (enc_secret_size + 2) >> 8; buf[3] = (enc_secret_size + 2) & 0xff; buf[4] = enc_secret_size >> 8; buf[5] = enc_secret_size & 0xff; generate_master_secret(ssl, premaster_secret); return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, enc_secret_size+6); }
static void gen_signature(const RSA_CTX *rsa_ctx, const uint8_t *sha_dgst, uint8_t *buf, int *offset) { static const uint8_t asn1_sig[] = { ASN1_SEQUENCE, 0x21, ASN1_SEQUENCE, 0x09, ASN1_OID, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* sha1 (1 3 14 3 2 26) */ ASN1_NULL, 0x00, ASN1_OCTET_STRING, 0x14 }; uint8_t *enc_block = (uint8_t *)alloca(rsa_ctx->num_octets); uint8_t *block = (uint8_t *)alloca(sizeof(asn1_sig) + SHA1_SIZE); int sig_size; /* add the digest as an embedded asn.1 sequence */ memcpy(block, asn1_sig, sizeof(asn1_sig)); memcpy(&block[sizeof(asn1_sig)], sha_dgst, SHA1_SIZE); sig_size = RSA_encrypt(rsa_ctx, block, sizeof(asn1_sig) + SHA1_SIZE, enc_block, 1); buf[(*offset)++] = ASN1_BIT_STRING; set_gen_length(sig_size+1, buf, offset); buf[(*offset)++] = 0; /* bit string is multiple of 8 */ memcpy(&buf[*offset], enc_block, sig_size); *offset += sig_size; }
/** * Sign the signature file. * * An MD5 digest is calculated over the firmware image and added to the * signature file. The signature file is signed by encrypting it using * the RSA private key. * @param data - pointer to firmware image * @param size - size of firmware image * @param rsa_keystring */ void util_sign(UCHAR *data, ULONG size, char *rsa_keyfile) { int i; MD5_CTX md5_context; fwHeader *pHeader = (fwHeader *)data; /* Calculate message digest over the code image */ MD5_Init(&md5_context); MD5_Update(&md5_context, &data[sizeof(fwHeader)], pHeader->info.length); MD5_Final(&sig.md5_digest[0], &md5_context); printf("Digest: "); for (i = 0; i < MD5_SIZE; i++) { printf("%02x", sig.md5_digest[i]); } printf("\n"); /* Copy firmware info to signature file */ memcpy(&sig.info, &pHeader->info, sizeof(fwInfo)); util_set_rsakey(rsa_keyfile); pHeader->siglength = RSA_encrypt(rsa_context, (uint8_t *)&sig, sizeof(sig), pHeader->sig, TRUE); printf("Signature length=%d\n", pHeader->siglength); }
/************************************************************************** * RSA tests * * Use the results from openssl to verify PKCS1 etc **************************************************************************/ static int RSA_test(void) { int res = 1; const char *plaintext = /* 128 byte hex number */ "1234567890abbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeeee2" "1aaaaaaaaaabbbbbbbbbbbbbbbccccccccccccccdddddddddddddeeeeeeeee2\012"; uint8_t enc_data[128], dec_data[128]; RSA_CTX *rsa_ctx = NULL; BI_CTX *bi_ctx; bigint *plaintext_bi; bigint *enc_data_bi, *dec_data_bi; uint8_t enc_data2[128], dec_data2[128]; int len; uint8_t *buf; /* extract the private key elements */ len = get_file("./axTLS.key_1024", &buf); if (asn1_get_private_key(buf, len, &rsa_ctx) < 0) { goto end; } free(buf); dump_frame("original data",(char *)plaintext, strlen(plaintext)); bi_ctx = rsa_ctx->bi_ctx; plaintext_bi = bi_import(bi_ctx, (const uint8_t *)plaintext, strlen(plaintext)); /* basic rsa encrypt */ enc_data_bi = RSA_public(rsa_ctx, plaintext_bi); bi_export(bi_ctx, bi_copy(enc_data_bi), enc_data, sizeof(enc_data)); dump_frame("encrypt data",(char *)enc_data, sizeof(enc_data)); /* basic rsa decrypt */ dec_data_bi = RSA_private(rsa_ctx, enc_data_bi); bi_export(bi_ctx, dec_data_bi, dec_data, sizeof(dec_data)); dump_frame("decrypt data",(char *)dec_data, sizeof(dec_data)); if (memcmp(dec_data, plaintext, strlen(plaintext))) { printf("Error: DECRYPT #1 failed\n"); goto end; } RSA_encrypt(rsa_ctx, (const uint8_t *)"abc", 3, enc_data2, 0); RSA_decrypt(rsa_ctx, enc_data2, dec_data2, 1); if (memcmp("abc", dec_data2, 3)) { printf("Error: ENCRYPT/DECRYPT #2 failed\n"); goto end; } RSA_free(rsa_ctx); res = 0; printf("All RSA tests passed\n"); end: return res; }
int RSA_public_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding) { size_t out_len; if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { return -1; } return out_len; }
std::vector <PGPMPI> pka_encrypt(const uint8_t pka, PGPMPI data, const std::vector <PGPMPI> & pub){ if (pka < 3){ // RSA return {RSA_encrypt(data, pub)}; } if (pka == 16){ // ElGamal return ElGamal_encrypt(data, pub); } else{ std::stringstream s; s << static_cast <unsigned int> (pka); throw std::runtime_error("Error: PKA number " + s.str() + " not allowed or unknown."); } return {}; // should never reach here; mainly just to remove compiler warnings }
int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding) { size_t out_len; if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { return -1; } if (out_len > INT_MAX) { OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); return -1; } return out_len; }
/* * Send a certificate verify message. */ static int send_cert_verify(SSL *ssl) { uint8_t *buf = ssl->bm_data; uint8_t dgst[MD5_SIZE+SHA1_SIZE]; RSA_CTX *rsa_ctx = ssl->ssl_ctx->rsa_ctx; int n = 0, ret; if (rsa_ctx == NULL) return SSL_OK; DISPLAY_RSA(ssl, rsa_ctx); buf[0] = HS_CERT_VERIFY; buf[1] = 0; finished_digest(ssl, NULL, dgst); /* calculate the digest */ /* rsa_ctx->bi_ctx is not thread-safe */ if (rsa_ctx) { SSL_CTX_LOCK(ssl->ssl_ctx->mutex); n = RSA_encrypt(rsa_ctx, dgst, sizeof(dgst), &buf[6], 1); SSL_CTX_UNLOCK(ssl->ssl_ctx->mutex); if (n == 0) { ret = SSL_ERROR_INVALID_KEY; goto error; } } buf[4] = n >> 8; /* add the RSA size (not officially documented) */ buf[5] = n & 0xff; n += 2; buf[2] = n >> 8; buf[3] = n & 0xff; ret = send_packet(ssl, PT_HANDSHAKE_PROTOCOL, NULL, n+4); error: return ret; }
int send_file(char* file_name, int sk) { FILE* file; FILE* fp; int name_size; // size of the name of the file to be sent int size,k_size; // size of the file to be sent int ret, i; unsigned char* buffer; // pointer to the buffer containing the file char* sym_key; int enckeysize; int remote_random,local_random; char* password; //***** recieve the random value from server *****// ret = recv(sk, &remote_random, sizeof(int), MSG_WAITALL); file = fopen("key","r"); /* Retrieve the size of the key to be sent */ fseek(file,0,SEEK_END); k_size = ftell(file); /* Memory allocation for the key to be sent */ sym_key = malloc(k_size * sizeof (char)); fseek(file, 0, SEEK_SET); /* Read key from file */ ret = fread(sym_key, 1, k_size, file); //***** RSA ENCRYPTION PART BEGIN *****// char* enckey; RSA* rsa = RSA_new(); fp = fopen("pub.pem","r"); PEM_read_RSAPublicKey(fp,&rsa,NULL,NULL); enckeysize =RSA_size(rsa); enckey=malloc(enckeysize * sizeof(char)); RSA_encrypt(sym_key,enckey,k_size,rsa); fclose(fp); //*** RSA ENCRYPTION PART end ***// /* Computation of the length of the filename */ name_size = strlen(file_name); /* Open the file to be sent */ file = fopen(file_name,"r"); if(file == NULL) { printf("\nError opening the file file\n"); return 1; } /* Retrieve the size of the file to be sent */ fseek(file,0,SEEK_END); size = ftell(file); /* Memory allocation for the file to be sent */ buffer = malloc(size * sizeof (char)); fseek(file, 0, SEEK_SET); /* File reading */ ret = fread(buffer, 1, size, file); if(ret < size) { printf("\n Error reading the file \n"); return 1; } fclose(file); /* The length of the file name is sent */ ret = send(sk, &name_size, sizeof(name_size), 0); if(ret != sizeof(name_size)){ printf("\n Error trasmitting the length of the file name\n "); return 1; } /* The file name is sent */ ret = send(sk, file_name, name_size, 0); if(ret < name_size){ printf("\n Error transmitting the file name\n "); return 1; } //****** Generate hash for freshness and origin(password) check *****// time_t t; int password_size; int fresh_size; char* fresh_txt; t = time(NULL); srand ( time(NULL)); local_random = rand(); file = fopen("passofA.txt","r"); fseek(file,0,SEEK_END); password_size = ftell(file); password = malloc(password_size * sizeof (char)); fseek(file, 0, SEEK_SET); ret = fread(password, 1, password_size, file); fclose(file); int pass_hash_len; const EVP_MD *md1; md1 = EVP_get_digestbyname("sha1"); unsigned char pass_md_value[EVP_MD_size(md1)]; pass_hash_len=hash_gen(password,&pass_md_value[0]); fresh_size=sizeof(password)+sizeof(local_random)+sizeof(remote_random); fresh_txt = malloc(fresh_size); int loc_rand_size=sizeof(local_random); int rem_rand_size = sizeof(remote_random); memcpy(fresh_txt,&pass_md_value[0],pass_hash_len); memcpy(&fresh_txt[pass_hash_len],&local_random,loc_rand_size); memcpy(&fresh_txt[pass_hash_len+loc_rand_size],&remote_random,rem_rand_size); const EVP_MD *md; md = EVP_get_digestbyname("sha1"); unsigned char md_value[EVP_MD_size(md)]; int md_len; md_len=hash_gen(fresh_txt,&md_value[0]); printf("\n Freshness Digest is: \n"); for(i = 0; i < md_len; i++) printbyte(md_value[i]); printf("\n"); ///*** SYMMETRIC KEY ENCRYPTION PART BEGIN ***/// char* totbuffer; int nctot; char *plaintext, *ciphertext; int totbufsize = size+md_len; totbuffer = malloc(totbufsize); // message + digest for freshness and password memcpy(totbuffer,buffer,size); memcpy(&totbuffer[size],md_value,md_len); ciphertext = malloc(totbufsize+128); nctot = symmetric_encrypt(totbuffer,ciphertext,totbufsize); // encrypted size //***** SYMMETRIC KEY encryption part END *****/// //***** concatenate enckey and ciphertext *****// char* textnkeynhash; int totsize; totsize=nctot+enckeysize+loc_rand_size; textnkeynhash=malloc(totsize); memcpy(textnkeynhash,ciphertext,nctot); memcpy(&textnkeynhash[nctot],enckey,enckeysize); memcpy(&textnkeynhash[nctot+enckeysize],&local_random,loc_rand_size); /* The file size is sent */ ret = send(sk, &totsize, sizeof(totsize), 0); if(ret != sizeof(size)){ printf("\n Error transmitting the file size\n "); return 1; } /* The file is sent */ ret = send(sk, textnkeynhash, totsize, 0); if(ret < size){ printf("\n Error transmitting the file\n"); return 1; } printf("\n File %s with size %d bytes has been sent\n", file_name, totsize); free(buffer); free(ciphertext); return 0; }
/** * Sends a REGISTER message in response to an ANNOUNCE or on timeout when * waiting for a KEYINFO or REG_CONF. If the register timeout expired, abort. */ void send_register(struct group_list_t *group) { struct uftp_h *header; struct register_h *reg; unsigned char *buf, *keydata; struct timeval now, send_time; unsigned int len, meslen; union key_t key; gettimeofday(&now, NULL); if (cmptimestamp(now, group->expire_time) >= 0) { glog1(group, "Registration unconfirmed by server"); send_abort(group, "Registration unconfirmed"); return; } buf = safe_calloc(MAXMTU, 1); header = (struct uftp_h *)buf; reg = (struct register_h *)(buf + sizeof(struct uftp_h)); keydata = (unsigned char *)reg + sizeof(struct register_h); set_uftp_header(header, REGISTER, group); reg->func = REGISTER; if (group->keytype != KEY_NONE) { memcpy(reg->rand2, group->rand2, RAND_LEN); if (group->keyextype == KEYEX_RSA) { if (has_proxy) { key = proxy_pubkey; } else { key = group->server_pubkey; } if (!RSA_encrypt(key.rsa, group->premaster, group->premaster_len, keydata, &len)) { glog0(group, "Error encrypting premaster secret"); send_abort(group, "Error encrypting premaster secret"); free(buf); return; } } else { uint16_t keylen; if (!export_EC_key(group->client_dhkey.ec, keydata, &keylen)) { glog0(group, "Error exporting ECDH public key"); send_abort(group, "Error exporting ECDH public key"); free(buf); return; } len = keylen; } reg->keyinfo_len = htons(len); } else { len = 0; } gettimeofday(&now, NULL); if (cmptimestamp(now, group->last_server_rx_ts) <= 0) { send_time = group->last_server_ts; } else { send_time = add_timeval(group->last_server_ts, diff_timeval(now, group->last_server_rx_ts)); } reg->tstamp_sec = htonl((uint32_t)send_time.tv_sec); reg->tstamp_usec = htonl((uint32_t)send_time.tv_usec); reg->hlen = (sizeof(struct register_h) + len) / 4; meslen = sizeof(struct uftp_h) + (reg->hlen * 4); if (nb_sendto(listener, buf, meslen, 0, (struct sockaddr *)&(group->replyaddr), family_len(group->replyaddr)) == SOCKET_ERROR) { gsockerror(group, "Error sending REGISTER"); } else { glog2(group, "REGISTER sent"); } glog3(group, "send time: %d.%06d", send_time.tv_sec, send_time.tv_usec); set_timeout(group, 0); if (group->client_auth) { send_client_key(group); } free(buf); }