bool rsa_ssh1_encrypt(unsigned char *data, int length, RSAKey *key) { mp_int *b1, *b2; int i; unsigned char *p; if (key->bytes < length + 4) return false; /* RSA key too short! */ memmove(data + key->bytes - length, data, length); data[0] = 0; data[1] = 2; size_t npad = key->bytes - length - 3; /* * Generate a sequence of nonzero padding bytes. We do this in a * reasonably uniform way and without having to loop round * retrying the random number generation, by first generating an * integer in [0,2^n) for an appropriately large n; then we * repeatedly multiply by 255 to give an integer in [0,255*2^n), * extract the top 8 bits to give an integer in [0,255), and mask * those bits off before multiplying up again for the next digit. * This gives us a sequence of numbers in [0,255), and of course * adding 1 to each of them gives numbers in [1,256) as we wanted. * * (You could imagine this being a sort of fixed-point operation: * given a uniformly random binary _fraction_, multiplying it by k * and subtracting off the integer part will yield you a sequence * of integers each in [0,k). I'm just doing that scaled up by a * power of 2 to avoid the fractions.) */ size_t random_bits = (npad + 16) * 8; mp_int *randval = mp_new(random_bits + 8); mp_int *tmp = mp_random_bits(random_bits); mp_copy_into(randval, tmp); mp_free(tmp); for (i = 2; i < key->bytes - length - 1; i++) { mp_mul_integer_into(randval, randval, 255); uint8_t byte = mp_get_byte(randval, random_bits / 8); assert(byte != 255); data[i] = byte + 1; mp_reduce_mod_2to(randval, random_bits); } mp_free(randval); data[key->bytes - length - 1] = 0; b1 = mp_from_bytes_be(make_ptrlen(data, key->bytes)); b2 = mp_modpow(b1, key->exponent, key->modulus); p = data; for (i = key->bytes; i--;) { *p++ = mp_get_byte(b2, i); } mp_free(b1); mp_free(b2); return true; }
void BinarySource_get_rsa_ssh1_pub( BinarySource *src, RSAKey *rsa, RsaSsh1Order order) { unsigned bits; mp_int *e, *m; bits = get_uint32(src); if (order == RSA_SSH1_EXPONENT_FIRST) { e = get_mp_ssh1(src); m = get_mp_ssh1(src); } else { m = get_mp_ssh1(src); e = get_mp_ssh1(src); } if (rsa) { rsa->bits = bits; rsa->exponent = e; rsa->modulus = m; rsa->bytes = (mp_get_nbits(m) + 7) / 8; } else { mp_free(e); mp_free(m); } }
static void tsfile_close_file(tsfile_t* file) { if(file->header) mp_free(file->header); mp_free(file->filename); close(file->fd); mp_cache_free(&tsfile_cache, file); }
static WeierstrassPoint *ecdsa_decode( ptrlen encoded, const struct ec_curve *curve) { assert(curve->type == EC_WEIERSTRASS); BinarySource src[1]; BinarySource_BARE_INIT_PL(src, encoded); unsigned char format_type = get_byte(src); WeierstrassPoint *P; size_t len = get_avail(src); mp_int *x; mp_int *y; switch (format_type) { case 0: /* The identity. */ P = ecc_weierstrass_point_new_identity(curve->w.wc); break; case 2: case 3: /* A compressed point, in which the x-coordinate is stored in * full, and y is deduced from that and a single bit * indicating its parity (stored in the format type byte). */ x = mp_from_bytes_be(get_data(src, len)); P = ecc_weierstrass_point_new_from_x(curve->w.wc, x, format_type & 1); mp_free(x); if (!P) /* this can fail if the input is invalid */ return NULL; break; case 4: /* An uncompressed point: the x,y coordinates are stored in * full. We expect the rest of the string to have even length, * and be divided half and half between the two values. */ if (len % 2 != 0) return NULL; len /= 2; x = mp_from_bytes_be(get_data(src, len)); y = mp_from_bytes_be(get_data(src, len)); P = ecc_weierstrass_point_new(curve->w.wc, x, y); mp_free(x); mp_free(y); break; default: /* An unrecognised type byte. */ return NULL; } /* Verify the point is on the curve */ if (!ecc_weierstrass_point_valid(P)) { ecc_weierstrass_point_free(P); return NULL; } return P; }
static char *eddsa_cache_str(ssh_key *key) { struct eddsa_key *ek = container_of(key, struct eddsa_key, sshk); mp_int *x, *y; ecc_edwards_get_affine(ek->publicKey, &x, &y); char *toret = ecc_cache_str_shared(ek->curve->name, x, y); mp_free(x); mp_free(y); return toret; }
void bam_plp_destroy(bam_plp_t iter) { mp_free(iter->mp, iter->dummy); mp_free(iter->mp, iter->head); if (iter->mp->cnt != 0) fprintf(pysamerr, "[bam_plp_destroy] memory leak: %d. Continue anyway.\n", iter->mp->cnt); mp_destroy(iter->mp); if (iter->b) bam_destroy1(iter->b); free(iter->plp); free(iter); }
void mpr_clear(mpr *op) { op->num.sign = 0; op->num.size = op->num.alloc = 0; mp_free(op->num.digs); op->den.sign = 0; op->den.size = op->den.alloc = 0; mp_free(op->den.digs); }
void bam_lplbuf_destroy(bam_lplbuf_t *tv) { freenode_t *p, *q; free(tv->cur_level); free(tv->pre_level); bam_plbuf_destroy(tv->plbuf); free(tv->aux); for (p = tv->head; p->next;) { q = p->next; mp_free(tv->mp, p); p = q; } mp_free(tv->mp, p); assert(tv->mp->cnt == 0); mp_destroy(tv->mp); free(tv); }
void mpi_clear(mpi *op) { op->sign = 0; op->size = op->alloc = 0; mp_free(op->digs); }
void freersakey(RSAKey *key) { freersapriv(key); if (key->modulus) { mp_free(key->modulus); key->modulus = NULL; } if (key->exponent) { mp_free(key->exponent); key->exponent = NULL; } if (key->comment) { sfree(key->comment); key->comment = NULL; } }
bool rsa_ssh1_decrypt_pkcs1(mp_int *input, RSAKey *key, strbuf *outbuf) { strbuf *data = strbuf_new_nm(); bool success = false; BinarySource src[1]; { mp_int *b = rsa_ssh1_decrypt(input, key); for (size_t i = (mp_get_nbits(key->modulus) + 7) / 8; i-- > 0 ;) { put_byte(data, mp_get_byte(b, i)); } mp_free(b); } BinarySource_BARE_INIT(src, data->u, data->len); /* Check PKCS#1 formatting prefix */ if (get_byte(src) != 0) goto out; if (get_byte(src) != 2) goto out; while (1) { unsigned char byte = get_byte(src); if (get_err(src)) goto out; if (byte == 0) break; } /* Everything else is the payload */ success = true; put_data(outbuf, get_ptr(src), get_avail(src)); out: strbuf_free(data); return success; }
PLATAPI int plat_closedir(plat_dir_t *dirp) { int ret = closedir(dirp->d_dirp); mp_free(dirp); return ret; }
bool mpi_set_str(mpi *p, const char *str, unsigned base) { ASSERT(p != NULL); ASSERT(str != NULL); while (*str && isspace(*str)) ++str; bool neg = false; if (*str == '+') { ++str; } else if (*str == '-') { neg = true; ++str; } mp_size size = 0; mp_digit *digits = mp_from_str(str, base, &size); if (digits) { mp_free(p->digits); p->digits = digits; p->size = p->alloc = size; p->sign = neg; return true; } return false; }
/** * Destroy all elements in queue and queue itself. Also notifies squeue_pop * Doesn't deallocate squeue_t * * @param sq synchronized queue to destroy * @param free helper to destroy element's data * * @note squeue_destroy() will notify consumer but doesn't guarantee that it \ * will leave squeue_pop(). You need to check this on your own. \ * It could be easily done by joining consumer thread. * */ void squeue_destroy(squeue_t* sq, void (*el_free)(void* obj)) { squeue_el_t* el; squeue_el_t* next; mutex_lock(&sq->sq_mutex); el = sq->sq_head; while(el != NULL) { next = el->s_next; el_free(el->s_data); mp_free(el); el = next; } sq->sq_is_destroyed = B_TRUE; cv_notify_all(&sq->sq_cv); mutex_unlock(&sq->sq_mutex); mutex_destroy(&sq->sq_mutex); cv_destroy(&sq->sq_cv); }
void mpi_free(mpi *n) { ASSERT(n != NULL); mp_free(n->digits); }
PLATAPI int plat_closedir(plat_dir_t *dirp) { FindClose(dirp->d_handle); mp_free(dirp); return 0; }
static mp_int *ecdsa_signing_exponent_from_data( const struct ec_curve *curve, const struct ecsign_extra *extra, ptrlen data) { /* Hash the data being signed. */ unsigned char hash[MAX_HASH_LEN]; ssh_hash *h = ssh_hash_new(extra->hash); put_datapl(h, data); ssh_hash_final(h, hash); /* * Take the leftmost b bits of the hash of the signed data (where * b is the number of bits in order(G)), interpreted big-endian. */ mp_int *z = mp_from_bytes_be(make_ptrlen(hash, extra->hash->hlen)); size_t zbits = mp_get_nbits(z); size_t nbits = mp_get_nbits(curve->w.G_order); size_t shift = zbits - nbits; /* Bound the shift count below at 0, using bit twiddling to avoid * a conditional branch */ shift &= ~-(shift >> (CHAR_BIT * sizeof(size_t) - 1)); mp_int *toret = mp_rshift_safe(z, shift); mp_free(z); return toret; }
/** * Reserviert den Speicher für die MPZ m von der Länge len * @param m MPZ für den der Speicher reserviert werden soll * @param len Länge der MPZ */ void mp_allocate(MPZ * m, unsigned int len){ if(m->allocated) mp_free(m); m->array = malloc(sizeof(uint32_t) * len); m->len = len; m->allocated = 1; }
/** * Extract element from synchronized queue. * If no elements on queue, blocks until squeue_push will add an element. * * May be called from multiple threads simultaneously, thread selected * in cv_notify_one wins (undetermined for most platforms). * * @param sq queue * * @return element or NULL if squeue is destroyed */ void* squeue_pop(squeue_t* sq) { squeue_el_t* el = NULL; void *object = NULL; mutex_lock(&sq->sq_mutex); retry: /* Try to extract element from head*/ el = sq->sq_head; if(el == NULL) { cv_wait(&sq->sq_cv, &sq->sq_mutex); if(!sq->sq_is_destroyed) goto retry; else return NULL; } /* Move backward */ sq->sq_head = el->s_next; /* Only one element left and it is head, * clear tail pointer*/ if(sq->sq_tail == sq->sq_head) { sq->sq_tail = NULL; } mutex_unlock(&sq->sq_mutex); object = el->s_data; mp_free(el); return object; }
static bool rsa2_verify(ssh_key *key, ptrlen sig, ptrlen data) { RSAKey *rsa = container_of(key, RSAKey, sshk); BinarySource src[1]; ptrlen type, in_pl; mp_int *in, *out; /* If we need to support variable flags on verify, this is where they go */ const ssh_hashalg *halg = rsa2_hash_alg_for_flags(0, NULL); /* Start by making sure the key is even long enough to encode a * signature. If not, everything fails to verify. */ size_t nbytes = (mp_get_nbits(rsa->modulus) + 7) / 8; if (nbytes < rsa_pkcs1_length_of_fixed_parts(halg)) return false; BinarySource_BARE_INIT_PL(src, sig); type = get_string(src); /* * RFC 4253 section 6.6: the signature integer in an ssh-rsa * signature is 'without lengths or padding'. That is, we _don't_ * expect the usual leading zero byte if the topmost bit of the * first byte is set. (However, because of the possibility of * BUG_SSH2_RSA_PADDING at the other end, we tolerate it if it's * there.) So we can't use get_mp_ssh2, which enforces that * leading-byte scheme; instead we use get_string and * mp_from_bytes_be, which will tolerate anything. */ in_pl = get_string(src); if (get_err(src) || !ptrlen_eq_string(type, "ssh-rsa")) return false; in = mp_from_bytes_be(in_pl); out = mp_modpow(in, rsa->exponent, rsa->modulus); mp_free(in); unsigned diff = 0; unsigned char *bytes = rsa_pkcs1_signature_string(nbytes, halg, data); for (size_t i = 0; i < nbytes; i++) diff |= bytes[nbytes-1 - i] ^ mp_get_byte(out, i); smemclr(bytes, nbytes); sfree(bytes); mp_free(out); return diff == 0; }
void mpi_free_zero(mpi *n) { ASSERT(n != NULL); mp_zero(n->digits, n->alloc); mp_free(n->digits); }
static struct ec_curve *ec_p384(void) { static struct ec_curve curve = { 0 }; static bool initialised = false; if (!initialised) { mp_int *p = MP_LITERAL(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff); mp_int *a = MP_LITERAL(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc); mp_int *b = MP_LITERAL(0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef); mp_int *G_x = MP_LITERAL(0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7); mp_int *G_y = MP_LITERAL(0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f); mp_int *G_order = MP_LITERAL(0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973); mp_int *nonsquare_mod_p = mp_from_integer(19); initialise_wcurve(&curve, p, a, b, nonsquare_mod_p, G_x, G_y, G_order); mp_free(p); mp_free(a); mp_free(b); mp_free(G_x); mp_free(G_y); mp_free(G_order); mp_free(nonsquare_mod_p); curve.textname = curve.name = "nistp384"; /* Now initialised, no need to do it again */ initialised = true; } return &curve; }
static bool eddsa_verify(ssh_key *key, ptrlen sig, ptrlen data) { struct eddsa_key *ek = container_of(key, struct eddsa_key, sshk); const struct ecsign_extra *extra = (const struct ecsign_extra *)ek->sshk.vt->extra; BinarySource src[1]; BinarySource_BARE_INIT_PL(src, sig); /* Check the signature starts with the algorithm name */ if (!ptrlen_eq_string(get_string(src), ek->sshk.vt->ssh_id)) return false; /* Now expect a single string which is the concatenation of an * encoded curve point r and an integer s. */ ptrlen sigstr = get_string(src); if (get_err(src)) return false; BinarySource_BARE_INIT_PL(src, sigstr); ptrlen rstr = get_data(src, ek->curve->fieldBytes); ptrlen sstr = get_data(src, ek->curve->fieldBytes); if (get_err(src) || get_avail(src)) return false; EdwardsPoint *r = eddsa_decode(rstr, ek->curve); if (!r) return false; mp_int *s = mp_from_bytes_le(sstr); mp_int *H = eddsa_signing_exponent_from_data(ek, extra, rstr, data); /* Verify that s*G == r + H*publicKey */ EdwardsPoint *lhs = ecc_edwards_multiply(ek->curve->e.G, s); mp_free(s); EdwardsPoint *hpk = ecc_edwards_multiply(ek->publicKey, H); mp_free(H); EdwardsPoint *rhs = ecc_edwards_add(r, hpk); ecc_edwards_point_free(hpk); unsigned valid = ecc_edwards_eq(lhs, rhs); ecc_edwards_point_free(lhs); ecc_edwards_point_free(rhs); ecc_edwards_point_free(r); return valid; }
static struct ec_curve *ec_p256(void) { static struct ec_curve curve = { 0 }; static bool initialised = false; if (!initialised) { mp_int *p = MP_LITERAL(0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff); mp_int *a = MP_LITERAL(0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc); mp_int *b = MP_LITERAL(0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b); mp_int *G_x = MP_LITERAL(0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296); mp_int *G_y = MP_LITERAL(0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5); mp_int *G_order = MP_LITERAL(0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551); mp_int *nonsquare_mod_p = mp_from_integer(3); initialise_wcurve(&curve, p, a, b, nonsquare_mod_p, G_x, G_y, G_order); mp_free(p); mp_free(a); mp_free(b); mp_free(G_x); mp_free(G_y); mp_free(G_order); mp_free(nonsquare_mod_p); curve.textname = curve.name = "nistp256"; /* Now initialised, no need to do it again */ initialised = true; } return &curve; }
static struct ec_curve *ec_p521(void) { static struct ec_curve curve = { 0 }; static bool initialised = false; if (!initialised) { mp_int *p = MP_LITERAL(0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); mp_int *a = MP_LITERAL(0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc); mp_int *b = MP_LITERAL(0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00); mp_int *G_x = MP_LITERAL(0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66); mp_int *G_y = MP_LITERAL(0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650); mp_int *G_order = MP_LITERAL(0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409); mp_int *nonsquare_mod_p = mp_from_integer(3); initialise_wcurve(&curve, p, a, b, nonsquare_mod_p, G_x, G_y, G_order); mp_free(p); mp_free(a); mp_free(b); mp_free(G_x); mp_free(G_y); mp_free(G_order); mp_free(nonsquare_mod_p); curve.textname = curve.name = "nistp521"; /* Now initialised, no need to do it again */ initialised = true; } return &curve; }
static struct ec_curve *ec_ed25519(void) { static struct ec_curve curve = { 0 }; static bool initialised = false; if (!initialised) { mp_int *p = MP_LITERAL(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed); mp_int *d = MP_LITERAL(0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3); mp_int *a = MP_LITERAL(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec); /* == p-1 */ mp_int *G_x = MP_LITERAL(0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a); mp_int *G_y = MP_LITERAL(0x6666666666666666666666666666666666666666666666666666666666666658); mp_int *G_order = MP_LITERAL(0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed); mp_int *nonsquare_mod_p = mp_from_integer(2); initialise_ecurve(&curve, p, d, a, nonsquare_mod_p, G_x, G_y, G_order); mp_free(p); mp_free(d); mp_free(a); mp_free(G_x); mp_free(G_y); mp_free(G_order); mp_free(nonsquare_mod_p); /* This curve doesn't need a name, because it's never used in * any format that embeds the curve name */ curve.name = NULL; curve.textname = "Ed25519"; /* Now initialised, no need to do it again */ initialised = true; } return &curve; }
void mq_free(MessageQueue *q) { mq_clear(q); while (q->pool != NULL) { MessageNode *n = q->pool; q->pool = q->pool->next; hv_free(n); } mp_free(&q->mp); }
/* Given an SSH-1 public key blob, determine its length. */ int rsa_ssh1_public_blob_len(ptrlen data) { BinarySource src[1]; BinarySource_BARE_INIT_PL(src, data); /* Expect a length word, then exponent and modulus. (It doesn't * even matter which order.) */ get_uint32(src); mp_free(get_mp_ssh1(src)); mp_free(get_mp_ssh1(src)); if (get_err(src)) return -1; /* Return the number of bytes consumed. */ return src->pos; }
static void eddsa_freekey(ssh_key *key) { struct eddsa_key *ek = container_of(key, struct eddsa_key, sshk); if (ek->publicKey) ecc_edwards_point_free(ek->publicKey); if (ek->privateKey) mp_free(ek->privateKey); sfree(ek); }
/* Remove a registry entry */ void registry_remove_entry(registry_entry_t *entry) { entry->hname_prev->hname_next = entry->hname_next; entry->hname_next->hname_prev = entry->hname_prev; entry->htype_prev->htype_next = entry->htype_next; entry->htype_next->htype_prev = entry->htype_prev; mp_free(entry); }