static bool pluto_init_nss(char *nssdb) { SECStatus rv; /* little lie, lsw_nss_setup doesn't have logging */ loglog(RC_LOG_SERIOUS, "NSS DB directory: sql:%s", nssdb); lsw_nss_buf_t err; if (!lsw_nss_setup(nssdb, LSW_NSS_READONLY, lsw_nss_get_password, err)) { loglog(RC_LOG_SERIOUS, "%s", err); return FALSE; } libreswan_log("NSS initialized"); /* * This exists purely to make the BSI happy. * We do not inflict this on other users */ if (pluto_nss_seedbits != 0) { int seedbytes = BYTES_FOR_BITS(pluto_nss_seedbits); unsigned char *buf = alloc_bytes(seedbytes,"TLA seedmix"); get_bsi_random(seedbytes, buf); /* much TLA, very blocking */ rv = PK11_RandomUpdate(buf, seedbytes); libreswan_log("seeded %d bytes into the NSS PRNG", seedbytes); passert(rv == SECSuccess); messupn(buf, seedbytes); pfree(buf); } return TRUE; }
static bool pluto_init_nss(char *nssdb) { SECStatus rv; char dbuf[1024]; snprintf(dbuf, sizeof(dbuf), "sql:%s", nssdb); loglog(RC_LOG_SERIOUS, "NSS DB directory: %s", dbuf); rv = NSS_Initialize(dbuf, "", "", SECMOD_DB, NSS_INIT_READONLY); if (rv != SECSuccess) { loglog(RC_LOG_SERIOUS, "NSS readonly initialization (\"%s\") failed (err %d)\n", dbuf, PR_GetError()); return FALSE; } libreswan_log("NSS initialized"); PK11_SetPasswordFunc(getNSSPassword); /* * This exists purely to make the BSI happy. * We do not inflict this on other users */ if (pluto_nss_seedbits != 0) { int seedbytes = BYTES_FOR_BITS(pluto_nss_seedbits); unsigned char *buf = alloc_bytes(seedbytes,"TLA seedmix"); get_bsi_random(seedbytes, buf); /* much TLA, very blocking */ rv = PK11_RandomUpdate(buf, seedbytes); libreswan_log("seeded %d bytes into the NSS PRNG", seedbytes); passert(rv == SECSuccess); messupn(buf, seedbytes); pfree(buf); } return TRUE; }
/* - bundle - bundle e and n into an RFC2537-format lump * Note, calls hexOut. * * NOTE: returns a pointer into a STATIC buffer */ static const unsigned char *bundle(int e, SECItem *n, size_t *sizep) { const char *hexp = hexOut(n); static unsigned char bundbuf[2 + BYTES_FOR_BITS(MAXBITS)]; const char *er; size_t size; assert(e <= 255); bundbuf[0] = 1; bundbuf[1] = e; er = ttodata(hexp, 0, 0, (char *)bundbuf + 2, sizeof(bundbuf) - 2, &size); if (er != NULL) { fprintf(stderr, "%s: can't-happen bundle convert error `%s'\n", me, er); exit(1); } if (size > sizeof(bundbuf) - 2) { fprintf(stderr, "%s: can't-happen bundle overflow (need %d)\n", me, (int) size); exit(1); } if (sizep != NULL) *sizep = size + 2; return bundbuf; }
/* * hexOut - prepare hex output, guaranteeing even number of digits. * (The current Libreswan conversion routines expect an even digit count.) * * NOTE: result is a pointer into a STATIC buffer. */ static const char *hexOut(SECItem *data) { unsigned i; static char hexbuf[3 + BYTES_FOR_BITS(MAXBITS) * 2]; char *hexp = hexbuf; if (data->len > BYTES_FOR_BITS(MAXBITS)) return "[too many bytes]"; *hexp++ = '0'; *hexp++ = 'x'; for (i = 0; i < data->len; i++, hexp += 2) sprintf(hexp, "%02x", data->data[i]); return hexbuf; }
/* * UpdateRNG - Updates NSS's PRNG with user generated entropy * * pluto and rsasigkey use the NSS crypto library as its random source. * Some government Three Letter Agencies require that pluto reads additional * bits from /dev/random and feed these into the NSS RNG before drawing random * from the NSS library, despite the NSS library itself already seeding its * internal state. This process can block pluto or rsasigkey for an extended * time during startup, depending on the entropy of the system. Therefore * the default is to not perform this redundant seeding. If specifying a * value, it is recommended to specify at least 460 bits (for FIPS) or 440 * bits (for BSI). */ static void UpdateNSS_RNG(int seedbits) { SECStatus rv; int seedbytes = BYTES_FOR_BITS(seedbits); unsigned char *buf = alloc_bytes(seedbytes,"TLA seedmix"); lsw_random(seedbytes, buf); rv = PK11_RandomUpdate(buf, seedbytes); assert(rv == SECSuccess); messupn(buf, seedbytes); pfree(buf); }
/* * bundle - bundle e and n into an RFC2537-format chunk_t */ static char *base64_bundle(int e, chunk_t modulus) { /* * Pack the single-byte exponent into a byte array. */ assert(e <= 255); u_char exponent_byte = 1; chunk_t exponent = { .ptr = &exponent_byte, .len = 1, }; /* * Create the resource record. */ char *bundle; err_t err = rsa_pubkey_to_base64(exponent, modulus, &bundle); if (err) { fprintf(stderr, "%s: can't-happen bundle convert error `%s'\n", progname, err); exit(1); } return bundle; } /* UpdateRNG - Updates NSS's PRNG with user generated entropy. */ static void UpdateNSS_RNG(int seedbits) { SECStatus rv; int seedbytes = BYTES_FOR_BITS(seedbits); unsigned char *buf = alloc_bytes(seedbytes,"TLA seedmix"); getrandom(seedbytes, buf); rv = PK11_RandomUpdate(buf, seedbytes); assert(rv == SECSuccess); messupn(buf, seedbytes); pfree(buf); }
/* * Size represents the length of the filter in BITS. */ bool bloom_init(bloom_t* bloom, size_t size, uint nfuncs, ...) { va_list arg_list; if ((bloom->bits = (unsigned char*) calloc(BYTES_FOR_BITS(size), sizeof(char))) == NULL) { return FALSE; } if ((bloom->funcs = (bloomhash_t*) calloc(nfuncs, sizeof(bloomhash_t))) == NULL) { free(bloom->bits); return FALSE; } bloom->bits_size = size; bloom->nfuncs = nfuncs; va_start(arg_list, nfuncs); while (nfuncs-- > 0) { bloom->funcs[nfuncs] = va_arg(arg_list, bloomhash_t); } va_end(arg_list); return TRUE; }
#endif } /* Oakley group description * * See: * RFC-2409 "The Internet key exchange (IKE)" Section 6 * RFC-3526 "More Modular Exponential (MODP) Diffie-Hellman groups" */ const struct oakley_group_desc unset_group = { 0, NULL, NULL, 0 }; /* magic signifier */ const struct oakley_group_desc oakley_group[] = { /* modp768_modulus no longer supported - too weak */ { OAKLEY_GROUP_MODP1024, &groupgenerator, &modp1024_modulus, BYTES_FOR_BITS(1024) }, { OAKLEY_GROUP_MODP1536, &groupgenerator, &modp1536_modulus, BYTES_FOR_BITS(1536) }, { OAKLEY_GROUP_MODP2048, &groupgenerator, &modp2048_modulus, BYTES_FOR_BITS(2048) }, { OAKLEY_GROUP_MODP3072, &groupgenerator, &modp3072_modulus, BYTES_FOR_BITS(3072) }, { OAKLEY_GROUP_MODP4096, &groupgenerator, &modp4096_modulus, BYTES_FOR_BITS(4096) }, { OAKLEY_GROUP_MODP6144, &groupgenerator, &modp6144_modulus, BYTES_FOR_BITS(6144) }, { OAKLEY_GROUP_MODP8192, &groupgenerator, &modp8192_modulus, BYTES_FOR_BITS(8192) }, { OAKLEY_GROUP_DH22, &generator_dh22, &dh22_modulus, BYTES_FOR_BITS( 1024) }, { OAKLEY_GROUP_DH23, &generator_dh23, &dh23_modulus, BYTES_FOR_BITS(
/* * See: https://tools.ietf.org/html/rfc2857 * * While NSS seemingly supports RIPEMD160, let's not go there. */ const struct integ_desc ike_alg_integ_hmac_ripemd_160_96 = { .common = { .name = "ripemd", .fqn = "HMAC_RIPEMD_160_96", .names = { "ripemd", "hmac_ripemd", "hmac_ripemd_160_96", }, .algo_type = IKE_ALG_INTEG, .id = { [IKEv1_OAKLEY_ID] = -1, [IKEv1_ESP_ID] = AUTH_ALGORITHM_HMAC_RIPEMD, [IKEv2_ALG_ID] = -1, }, }, .integ_keymat_size = BYTES_FOR_BITS(160), .integ_output_size = BYTES_FOR_BITS(96), .integ_ikev1_ah_transform = AH_RIPEMD, #ifdef SADB_X_AALG_RIPEMD160HMAC .integ_sadb_aalg_id = SADB_X_AALG_RIPEMD160HMAC, #endif .integ_netlink_xfrm_name = "hmac(rmd160)", .integ_tcpdump_name = "ripemd", .integ_ike_audit_name = "ripemd", .integ_kernel_audit_name = "HMAC_RIPEMD", };
void bloom_reset(bloom_t* bloom) { memset(bloom->bits, 0, BYTES_FOR_BITS(bloom->bits_size)); }