1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * Wrapper functions for libnettle and libgmp 3e5b75505Sopenharmony_ci * Copyright (c) 2017, Jouni Malinen <j@w1.fi> 4e5b75505Sopenharmony_ci * 5e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 6e5b75505Sopenharmony_ci * See README for more details. 7e5b75505Sopenharmony_ci */ 8e5b75505Sopenharmony_ci 9e5b75505Sopenharmony_ci#include "includes.h" 10e5b75505Sopenharmony_ci#include <nettle/nettle-meta.h> 11e5b75505Sopenharmony_ci#include <nettle/des.h> 12e5b75505Sopenharmony_ci#undef des_encrypt 13e5b75505Sopenharmony_ci#include <nettle/hmac.h> 14e5b75505Sopenharmony_ci#include <nettle/aes.h> 15e5b75505Sopenharmony_ci#undef aes_encrypt 16e5b75505Sopenharmony_ci#undef aes_decrypt 17e5b75505Sopenharmony_ci#include <nettle/arcfour.h> 18e5b75505Sopenharmony_ci#include <nettle/bignum.h> 19e5b75505Sopenharmony_ci 20e5b75505Sopenharmony_ci#include "common.h" 21e5b75505Sopenharmony_ci#include "md5.h" 22e5b75505Sopenharmony_ci#include "sha1.h" 23e5b75505Sopenharmony_ci#include "sha256.h" 24e5b75505Sopenharmony_ci#include "sha384.h" 25e5b75505Sopenharmony_ci#include "sha512.h" 26e5b75505Sopenharmony_ci#include "crypto.h" 27e5b75505Sopenharmony_ci 28e5b75505Sopenharmony_ci 29e5b75505Sopenharmony_ciint des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 30e5b75505Sopenharmony_ci{ 31e5b75505Sopenharmony_ci struct des_ctx ctx; 32e5b75505Sopenharmony_ci u8 pkey[8], next, tmp; 33e5b75505Sopenharmony_ci int i; 34e5b75505Sopenharmony_ci 35e5b75505Sopenharmony_ci /* Add parity bits to the key */ 36e5b75505Sopenharmony_ci next = 0; 37e5b75505Sopenharmony_ci for (i = 0; i < 7; i++) { 38e5b75505Sopenharmony_ci tmp = key[i]; 39e5b75505Sopenharmony_ci pkey[i] = (tmp >> i) | next | 1; 40e5b75505Sopenharmony_ci next = tmp << (7 - i); 41e5b75505Sopenharmony_ci } 42e5b75505Sopenharmony_ci pkey[i] = next | 1; 43e5b75505Sopenharmony_ci 44e5b75505Sopenharmony_ci nettle_des_set_key(&ctx, pkey); 45e5b75505Sopenharmony_ci nettle_des_encrypt(&ctx, DES_BLOCK_SIZE, cypher, clear); 46e5b75505Sopenharmony_ci os_memset(&ctx, 0, sizeof(ctx)); 47e5b75505Sopenharmony_ci return 0; 48e5b75505Sopenharmony_ci} 49e5b75505Sopenharmony_ci 50e5b75505Sopenharmony_ci 51e5b75505Sopenharmony_cistatic int nettle_digest_vector(const struct nettle_hash *alg, size_t num_elem, 52e5b75505Sopenharmony_ci const u8 *addr[], const size_t *len, u8 *mac) 53e5b75505Sopenharmony_ci{ 54e5b75505Sopenharmony_ci void *ctx; 55e5b75505Sopenharmony_ci size_t i; 56e5b75505Sopenharmony_ci 57e5b75505Sopenharmony_ci if (TEST_FAIL()) 58e5b75505Sopenharmony_ci return -1; 59e5b75505Sopenharmony_ci 60e5b75505Sopenharmony_ci ctx = os_malloc(alg->context_size); 61e5b75505Sopenharmony_ci if (!ctx) 62e5b75505Sopenharmony_ci return -1; 63e5b75505Sopenharmony_ci alg->init(ctx); 64e5b75505Sopenharmony_ci for (i = 0; i < num_elem; i++) 65e5b75505Sopenharmony_ci alg->update(ctx, len[i], addr[i]); 66e5b75505Sopenharmony_ci alg->digest(ctx, alg->digest_size, mac); 67e5b75505Sopenharmony_ci bin_clear_free(ctx, alg->context_size); 68e5b75505Sopenharmony_ci return 0; 69e5b75505Sopenharmony_ci} 70e5b75505Sopenharmony_ci 71e5b75505Sopenharmony_ci 72e5b75505Sopenharmony_ciint md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 73e5b75505Sopenharmony_ci{ 74e5b75505Sopenharmony_ci return nettle_digest_vector(&nettle_md4, num_elem, addr, len, mac); 75e5b75505Sopenharmony_ci} 76e5b75505Sopenharmony_ci 77e5b75505Sopenharmony_ci 78e5b75505Sopenharmony_ciint md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 79e5b75505Sopenharmony_ci{ 80e5b75505Sopenharmony_ci return nettle_digest_vector(&nettle_md5, num_elem, addr, len, mac); 81e5b75505Sopenharmony_ci} 82e5b75505Sopenharmony_ci 83e5b75505Sopenharmony_ci 84e5b75505Sopenharmony_ciint sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 85e5b75505Sopenharmony_ci{ 86e5b75505Sopenharmony_ci return nettle_digest_vector(&nettle_sha1, num_elem, addr, len, mac); 87e5b75505Sopenharmony_ci} 88e5b75505Sopenharmony_ci 89e5b75505Sopenharmony_ci 90e5b75505Sopenharmony_ciint sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 91e5b75505Sopenharmony_ci{ 92e5b75505Sopenharmony_ci return nettle_digest_vector(&nettle_sha256, num_elem, addr, len, mac); 93e5b75505Sopenharmony_ci} 94e5b75505Sopenharmony_ci 95e5b75505Sopenharmony_ci 96e5b75505Sopenharmony_ciint sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 97e5b75505Sopenharmony_ci{ 98e5b75505Sopenharmony_ci return nettle_digest_vector(&nettle_sha384, num_elem, addr, len, mac); 99e5b75505Sopenharmony_ci} 100e5b75505Sopenharmony_ci 101e5b75505Sopenharmony_ci 102e5b75505Sopenharmony_ciint sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 103e5b75505Sopenharmony_ci{ 104e5b75505Sopenharmony_ci return nettle_digest_vector(&nettle_sha512, num_elem, addr, len, mac); 105e5b75505Sopenharmony_ci} 106e5b75505Sopenharmony_ci 107e5b75505Sopenharmony_ci 108e5b75505Sopenharmony_ciint hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, 109e5b75505Sopenharmony_ci const u8 *addr[], const size_t *len, u8 *mac) 110e5b75505Sopenharmony_ci{ 111e5b75505Sopenharmony_ci struct hmac_md5_ctx ctx; 112e5b75505Sopenharmony_ci size_t i; 113e5b75505Sopenharmony_ci 114e5b75505Sopenharmony_ci if (TEST_FAIL()) 115e5b75505Sopenharmony_ci return -1; 116e5b75505Sopenharmony_ci 117e5b75505Sopenharmony_ci hmac_md5_set_key(&ctx, key_len, key); 118e5b75505Sopenharmony_ci for (i = 0; i < num_elem; i++) 119e5b75505Sopenharmony_ci hmac_md5_update(&ctx, len[i], addr[i]); 120e5b75505Sopenharmony_ci hmac_md5_digest(&ctx, MD5_DIGEST_SIZE, mac); 121e5b75505Sopenharmony_ci os_memset(&ctx, 0, sizeof(ctx)); 122e5b75505Sopenharmony_ci return 0; 123e5b75505Sopenharmony_ci} 124e5b75505Sopenharmony_ci 125e5b75505Sopenharmony_ci 126e5b75505Sopenharmony_ciint hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, 127e5b75505Sopenharmony_ci u8 *mac) 128e5b75505Sopenharmony_ci{ 129e5b75505Sopenharmony_ci return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac); 130e5b75505Sopenharmony_ci} 131e5b75505Sopenharmony_ci 132e5b75505Sopenharmony_ci 133e5b75505Sopenharmony_ciint hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, 134e5b75505Sopenharmony_ci const u8 *addr[], const size_t *len, u8 *mac) 135e5b75505Sopenharmony_ci{ 136e5b75505Sopenharmony_ci struct hmac_sha1_ctx ctx; 137e5b75505Sopenharmony_ci size_t i; 138e5b75505Sopenharmony_ci 139e5b75505Sopenharmony_ci if (TEST_FAIL()) 140e5b75505Sopenharmony_ci return -1; 141e5b75505Sopenharmony_ci 142e5b75505Sopenharmony_ci hmac_sha1_set_key(&ctx, key_len, key); 143e5b75505Sopenharmony_ci for (i = 0; i < num_elem; i++) 144e5b75505Sopenharmony_ci hmac_sha1_update(&ctx, len[i], addr[i]); 145e5b75505Sopenharmony_ci hmac_sha1_digest(&ctx, SHA1_DIGEST_SIZE, mac); 146e5b75505Sopenharmony_ci os_memset(&ctx, 0, sizeof(ctx)); 147e5b75505Sopenharmony_ci return 0; 148e5b75505Sopenharmony_ci} 149e5b75505Sopenharmony_ci 150e5b75505Sopenharmony_ci 151e5b75505Sopenharmony_ciint hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, 152e5b75505Sopenharmony_ci u8 *mac) 153e5b75505Sopenharmony_ci{ 154e5b75505Sopenharmony_ci return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac); 155e5b75505Sopenharmony_ci} 156e5b75505Sopenharmony_ci 157e5b75505Sopenharmony_ci 158e5b75505Sopenharmony_ci#ifdef CONFIG_SHA256 159e5b75505Sopenharmony_ci 160e5b75505Sopenharmony_ciint hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, 161e5b75505Sopenharmony_ci const u8 *addr[], const size_t *len, u8 *mac) 162e5b75505Sopenharmony_ci{ 163e5b75505Sopenharmony_ci struct hmac_sha256_ctx ctx; 164e5b75505Sopenharmony_ci size_t i; 165e5b75505Sopenharmony_ci 166e5b75505Sopenharmony_ci if (TEST_FAIL()) 167e5b75505Sopenharmony_ci return -1; 168e5b75505Sopenharmony_ci 169e5b75505Sopenharmony_ci hmac_sha256_set_key(&ctx, key_len, key); 170e5b75505Sopenharmony_ci for (i = 0; i < num_elem; i++) 171e5b75505Sopenharmony_ci hmac_sha256_update(&ctx, len[i], addr[i]); 172e5b75505Sopenharmony_ci hmac_sha256_digest(&ctx, SHA256_DIGEST_SIZE, mac); 173e5b75505Sopenharmony_ci os_memset(&ctx, 0, sizeof(ctx)); 174e5b75505Sopenharmony_ci return 0; 175e5b75505Sopenharmony_ci} 176e5b75505Sopenharmony_ci 177e5b75505Sopenharmony_ci 178e5b75505Sopenharmony_ciint hmac_sha256(const u8 *key, size_t key_len, const u8 *data, 179e5b75505Sopenharmony_ci size_t data_len, u8 *mac) 180e5b75505Sopenharmony_ci{ 181e5b75505Sopenharmony_ci return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); 182e5b75505Sopenharmony_ci} 183e5b75505Sopenharmony_ci 184e5b75505Sopenharmony_ci#endif /* CONFIG_SHA256 */ 185e5b75505Sopenharmony_ci 186e5b75505Sopenharmony_ci 187e5b75505Sopenharmony_ci#ifdef CONFIG_SHA384 188e5b75505Sopenharmony_ci 189e5b75505Sopenharmony_ciint hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, 190e5b75505Sopenharmony_ci const u8 *addr[], const size_t *len, u8 *mac) 191e5b75505Sopenharmony_ci{ 192e5b75505Sopenharmony_ci struct hmac_sha384_ctx ctx; 193e5b75505Sopenharmony_ci size_t i; 194e5b75505Sopenharmony_ci 195e5b75505Sopenharmony_ci if (TEST_FAIL()) 196e5b75505Sopenharmony_ci return -1; 197e5b75505Sopenharmony_ci 198e5b75505Sopenharmony_ci hmac_sha384_set_key(&ctx, key_len, key); 199e5b75505Sopenharmony_ci for (i = 0; i < num_elem; i++) 200e5b75505Sopenharmony_ci hmac_sha384_update(&ctx, len[i], addr[i]); 201e5b75505Sopenharmony_ci hmac_sha384_digest(&ctx, SHA384_DIGEST_SIZE, mac); 202e5b75505Sopenharmony_ci os_memset(&ctx, 0, sizeof(ctx)); 203e5b75505Sopenharmony_ci return 0; 204e5b75505Sopenharmony_ci} 205e5b75505Sopenharmony_ci 206e5b75505Sopenharmony_ci 207e5b75505Sopenharmony_ciint hmac_sha384(const u8 *key, size_t key_len, const u8 *data, 208e5b75505Sopenharmony_ci size_t data_len, u8 *mac) 209e5b75505Sopenharmony_ci{ 210e5b75505Sopenharmony_ci return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac); 211e5b75505Sopenharmony_ci} 212e5b75505Sopenharmony_ci 213e5b75505Sopenharmony_ci#endif /* CONFIG_SHA384 */ 214e5b75505Sopenharmony_ci 215e5b75505Sopenharmony_ci 216e5b75505Sopenharmony_ci#ifdef CONFIG_SHA512 217e5b75505Sopenharmony_ci 218e5b75505Sopenharmony_ciint hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem, 219e5b75505Sopenharmony_ci const u8 *addr[], const size_t *len, u8 *mac) 220e5b75505Sopenharmony_ci{ 221e5b75505Sopenharmony_ci struct hmac_sha512_ctx ctx; 222e5b75505Sopenharmony_ci size_t i; 223e5b75505Sopenharmony_ci 224e5b75505Sopenharmony_ci if (TEST_FAIL()) 225e5b75505Sopenharmony_ci return -1; 226e5b75505Sopenharmony_ci 227e5b75505Sopenharmony_ci hmac_sha512_set_key(&ctx, key_len, key); 228e5b75505Sopenharmony_ci for (i = 0; i < num_elem; i++) 229e5b75505Sopenharmony_ci hmac_sha512_update(&ctx, len[i], addr[i]); 230e5b75505Sopenharmony_ci hmac_sha512_digest(&ctx, SHA512_DIGEST_SIZE, mac); 231e5b75505Sopenharmony_ci os_memset(&ctx, 0, sizeof(ctx)); 232e5b75505Sopenharmony_ci return 0; 233e5b75505Sopenharmony_ci} 234e5b75505Sopenharmony_ci 235e5b75505Sopenharmony_ci 236e5b75505Sopenharmony_ciint hmac_sha512(const u8 *key, size_t key_len, const u8 *data, 237e5b75505Sopenharmony_ci size_t data_len, u8 *mac) 238e5b75505Sopenharmony_ci{ 239e5b75505Sopenharmony_ci return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac); 240e5b75505Sopenharmony_ci} 241e5b75505Sopenharmony_ci 242e5b75505Sopenharmony_ci#endif /* CONFIG_SHA512 */ 243e5b75505Sopenharmony_ci 244e5b75505Sopenharmony_ci 245e5b75505Sopenharmony_civoid * aes_encrypt_init(const u8 *key, size_t len) 246e5b75505Sopenharmony_ci{ 247e5b75505Sopenharmony_ci struct aes_ctx *ctx; 248e5b75505Sopenharmony_ci 249e5b75505Sopenharmony_ci if (TEST_FAIL()) 250e5b75505Sopenharmony_ci return NULL; 251e5b75505Sopenharmony_ci ctx = os_malloc(sizeof(*ctx)); 252e5b75505Sopenharmony_ci if (!ctx) 253e5b75505Sopenharmony_ci return NULL; 254e5b75505Sopenharmony_ci 255e5b75505Sopenharmony_ci nettle_aes_set_encrypt_key(ctx, len, key); 256e5b75505Sopenharmony_ci 257e5b75505Sopenharmony_ci return ctx; 258e5b75505Sopenharmony_ci} 259e5b75505Sopenharmony_ci 260e5b75505Sopenharmony_ci 261e5b75505Sopenharmony_ciint aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 262e5b75505Sopenharmony_ci{ 263e5b75505Sopenharmony_ci struct aes_ctx *actx = ctx; 264e5b75505Sopenharmony_ci nettle_aes_encrypt(actx, AES_BLOCK_SIZE, crypt, plain); 265e5b75505Sopenharmony_ci return 0; 266e5b75505Sopenharmony_ci} 267e5b75505Sopenharmony_ci 268e5b75505Sopenharmony_ci 269e5b75505Sopenharmony_civoid aes_encrypt_deinit(void *ctx) 270e5b75505Sopenharmony_ci{ 271e5b75505Sopenharmony_ci struct aes_ctx *actx = ctx; 272e5b75505Sopenharmony_ci bin_clear_free(actx, sizeof(*actx)); 273e5b75505Sopenharmony_ci} 274e5b75505Sopenharmony_ci 275e5b75505Sopenharmony_ci 276e5b75505Sopenharmony_civoid * aes_decrypt_init(const u8 *key, size_t len) 277e5b75505Sopenharmony_ci{ 278e5b75505Sopenharmony_ci struct aes_ctx *ctx; 279e5b75505Sopenharmony_ci 280e5b75505Sopenharmony_ci if (TEST_FAIL()) 281e5b75505Sopenharmony_ci return NULL; 282e5b75505Sopenharmony_ci ctx = os_malloc(sizeof(*ctx)); 283e5b75505Sopenharmony_ci if (!ctx) 284e5b75505Sopenharmony_ci return NULL; 285e5b75505Sopenharmony_ci 286e5b75505Sopenharmony_ci nettle_aes_set_decrypt_key(ctx, len, key); 287e5b75505Sopenharmony_ci 288e5b75505Sopenharmony_ci return ctx; 289e5b75505Sopenharmony_ci} 290e5b75505Sopenharmony_ci 291e5b75505Sopenharmony_ci 292e5b75505Sopenharmony_ciint aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 293e5b75505Sopenharmony_ci{ 294e5b75505Sopenharmony_ci struct aes_ctx *actx = ctx; 295e5b75505Sopenharmony_ci nettle_aes_decrypt(actx, AES_BLOCK_SIZE, plain, crypt); 296e5b75505Sopenharmony_ci return 0; 297e5b75505Sopenharmony_ci} 298e5b75505Sopenharmony_ci 299e5b75505Sopenharmony_ci 300e5b75505Sopenharmony_civoid aes_decrypt_deinit(void *ctx) 301e5b75505Sopenharmony_ci{ 302e5b75505Sopenharmony_ci struct aes_ctx *actx = ctx; 303e5b75505Sopenharmony_ci bin_clear_free(actx, sizeof(*actx)); 304e5b75505Sopenharmony_ci} 305e5b75505Sopenharmony_ci 306e5b75505Sopenharmony_ci 307e5b75505Sopenharmony_ciint crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, 308e5b75505Sopenharmony_ci u8 *pubkey) 309e5b75505Sopenharmony_ci{ 310e5b75505Sopenharmony_ci size_t pubkey_len, pad; 311e5b75505Sopenharmony_ci 312e5b75505Sopenharmony_ci if (os_get_random(privkey, prime_len) < 0) 313e5b75505Sopenharmony_ci return -1; 314e5b75505Sopenharmony_ci if (os_memcmp(privkey, prime, prime_len) > 0) { 315e5b75505Sopenharmony_ci /* Make sure private value is smaller than prime */ 316e5b75505Sopenharmony_ci privkey[0] = 0; 317e5b75505Sopenharmony_ci } 318e5b75505Sopenharmony_ci 319e5b75505Sopenharmony_ci pubkey_len = prime_len; 320e5b75505Sopenharmony_ci if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len, 321e5b75505Sopenharmony_ci pubkey, &pubkey_len) < 0) 322e5b75505Sopenharmony_ci return -1; 323e5b75505Sopenharmony_ci if (pubkey_len < prime_len) { 324e5b75505Sopenharmony_ci pad = prime_len - pubkey_len; 325e5b75505Sopenharmony_ci os_memmove(pubkey + pad, pubkey, pubkey_len); 326e5b75505Sopenharmony_ci os_memset(pubkey, 0, pad); 327e5b75505Sopenharmony_ci } 328e5b75505Sopenharmony_ci 329e5b75505Sopenharmony_ci return 0; 330e5b75505Sopenharmony_ci} 331e5b75505Sopenharmony_ci 332e5b75505Sopenharmony_ci 333e5b75505Sopenharmony_ciint crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len, 334e5b75505Sopenharmony_ci const u8 *order, size_t order_len, 335e5b75505Sopenharmony_ci const u8 *privkey, size_t privkey_len, 336e5b75505Sopenharmony_ci const u8 *pubkey, size_t pubkey_len, 337e5b75505Sopenharmony_ci u8 *secret, size_t *len) 338e5b75505Sopenharmony_ci{ 339e5b75505Sopenharmony_ci mpz_t pub; 340e5b75505Sopenharmony_ci int res = -1; 341e5b75505Sopenharmony_ci 342e5b75505Sopenharmony_ci if (pubkey_len > prime_len || 343e5b75505Sopenharmony_ci (pubkey_len == prime_len && 344e5b75505Sopenharmony_ci os_memcmp(pubkey, prime, prime_len) >= 0)) 345e5b75505Sopenharmony_ci return -1; 346e5b75505Sopenharmony_ci 347e5b75505Sopenharmony_ci mpz_init(pub); 348e5b75505Sopenharmony_ci mpz_import(pub, pubkey_len, 1, 1, 1, 0, pubkey); 349e5b75505Sopenharmony_ci if (mpz_cmp_d(pub, 1) <= 0) 350e5b75505Sopenharmony_ci goto fail; 351e5b75505Sopenharmony_ci 352e5b75505Sopenharmony_ci if (order) { 353e5b75505Sopenharmony_ci mpz_t p, q, tmp; 354e5b75505Sopenharmony_ci int failed; 355e5b75505Sopenharmony_ci 356e5b75505Sopenharmony_ci /* verify: pubkey^q == 1 mod p */ 357e5b75505Sopenharmony_ci mpz_inits(p, q, tmp, NULL); 358e5b75505Sopenharmony_ci mpz_import(p, prime_len, 1, 1, 1, 0, prime); 359e5b75505Sopenharmony_ci mpz_import(q, order_len, 1, 1, 1, 0, order); 360e5b75505Sopenharmony_ci mpz_powm(tmp, pub, q, p); 361e5b75505Sopenharmony_ci failed = mpz_cmp_d(tmp, 1) != 0; 362e5b75505Sopenharmony_ci mpz_clears(p, q, tmp, NULL); 363e5b75505Sopenharmony_ci if (failed) 364e5b75505Sopenharmony_ci goto fail; 365e5b75505Sopenharmony_ci } 366e5b75505Sopenharmony_ci 367e5b75505Sopenharmony_ci res = crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len, 368e5b75505Sopenharmony_ci prime, prime_len, secret, len); 369e5b75505Sopenharmony_cifail: 370e5b75505Sopenharmony_ci mpz_clear(pub); 371e5b75505Sopenharmony_ci return res; 372e5b75505Sopenharmony_ci} 373e5b75505Sopenharmony_ci 374e5b75505Sopenharmony_ci 375e5b75505Sopenharmony_ciint crypto_mod_exp(const u8 *base, size_t base_len, 376e5b75505Sopenharmony_ci const u8 *power, size_t power_len, 377e5b75505Sopenharmony_ci const u8 *modulus, size_t modulus_len, 378e5b75505Sopenharmony_ci u8 *result, size_t *result_len) 379e5b75505Sopenharmony_ci{ 380e5b75505Sopenharmony_ci mpz_t bn_base, bn_exp, bn_modulus, bn_result; 381e5b75505Sopenharmony_ci int ret = -1; 382e5b75505Sopenharmony_ci size_t len; 383e5b75505Sopenharmony_ci 384e5b75505Sopenharmony_ci mpz_inits(bn_base, bn_exp, bn_modulus, bn_result, NULL); 385e5b75505Sopenharmony_ci mpz_import(bn_base, base_len, 1, 1, 1, 0, base); 386e5b75505Sopenharmony_ci mpz_import(bn_exp, power_len, 1, 1, 1, 0, power); 387e5b75505Sopenharmony_ci mpz_import(bn_modulus, modulus_len, 1, 1, 1, 0, modulus); 388e5b75505Sopenharmony_ci 389e5b75505Sopenharmony_ci mpz_powm(bn_result, bn_base, bn_exp, bn_modulus); 390e5b75505Sopenharmony_ci len = mpz_sizeinbase(bn_result, 2); 391e5b75505Sopenharmony_ci len = (len + 7) / 8; 392e5b75505Sopenharmony_ci if (*result_len < len) 393e5b75505Sopenharmony_ci goto error; 394e5b75505Sopenharmony_ci mpz_export(result, result_len, 1, 1, 1, 0, bn_result); 395e5b75505Sopenharmony_ci ret = 0; 396e5b75505Sopenharmony_ci 397e5b75505Sopenharmony_cierror: 398e5b75505Sopenharmony_ci mpz_clears(bn_base, bn_exp, bn_modulus, bn_result, NULL); 399e5b75505Sopenharmony_ci return ret; 400e5b75505Sopenharmony_ci} 401e5b75505Sopenharmony_ci 402e5b75505Sopenharmony_ci 403e5b75505Sopenharmony_cistruct crypto_cipher { 404e5b75505Sopenharmony_ci enum crypto_cipher_alg alg; 405e5b75505Sopenharmony_ci union { 406e5b75505Sopenharmony_ci struct arcfour_ctx arcfour_ctx; 407e5b75505Sopenharmony_ci } u; 408e5b75505Sopenharmony_ci}; 409e5b75505Sopenharmony_ci 410e5b75505Sopenharmony_ci 411e5b75505Sopenharmony_cistruct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 412e5b75505Sopenharmony_ci const u8 *iv, const u8 *key, 413e5b75505Sopenharmony_ci size_t key_len) 414e5b75505Sopenharmony_ci{ 415e5b75505Sopenharmony_ci struct crypto_cipher *ctx; 416e5b75505Sopenharmony_ci 417e5b75505Sopenharmony_ci ctx = os_zalloc(sizeof(*ctx)); 418e5b75505Sopenharmony_ci if (!ctx) 419e5b75505Sopenharmony_ci return NULL; 420e5b75505Sopenharmony_ci 421e5b75505Sopenharmony_ci ctx->alg = alg; 422e5b75505Sopenharmony_ci 423e5b75505Sopenharmony_ci switch (alg) { 424e5b75505Sopenharmony_ci case CRYPTO_CIPHER_ALG_RC4: 425e5b75505Sopenharmony_ci nettle_arcfour_set_key(&ctx->u.arcfour_ctx, key_len, key); 426e5b75505Sopenharmony_ci break; 427e5b75505Sopenharmony_ci default: 428e5b75505Sopenharmony_ci os_free(ctx); 429e5b75505Sopenharmony_ci return NULL; 430e5b75505Sopenharmony_ci } 431e5b75505Sopenharmony_ci 432e5b75505Sopenharmony_ci return ctx; 433e5b75505Sopenharmony_ci} 434e5b75505Sopenharmony_ci 435e5b75505Sopenharmony_ci 436e5b75505Sopenharmony_ciint crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 437e5b75505Sopenharmony_ci u8 *crypt, size_t len) 438e5b75505Sopenharmony_ci{ 439e5b75505Sopenharmony_ci switch (ctx->alg) { 440e5b75505Sopenharmony_ci case CRYPTO_CIPHER_ALG_RC4: 441e5b75505Sopenharmony_ci nettle_arcfour_crypt(&ctx->u.arcfour_ctx, len, crypt, plain); 442e5b75505Sopenharmony_ci break; 443e5b75505Sopenharmony_ci default: 444e5b75505Sopenharmony_ci return -1; 445e5b75505Sopenharmony_ci } 446e5b75505Sopenharmony_ci 447e5b75505Sopenharmony_ci return 0; 448e5b75505Sopenharmony_ci} 449e5b75505Sopenharmony_ci 450e5b75505Sopenharmony_ci 451e5b75505Sopenharmony_ciint crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 452e5b75505Sopenharmony_ci u8 *plain, size_t len) 453e5b75505Sopenharmony_ci{ 454e5b75505Sopenharmony_ci switch (ctx->alg) { 455e5b75505Sopenharmony_ci case CRYPTO_CIPHER_ALG_RC4: 456e5b75505Sopenharmony_ci nettle_arcfour_crypt(&ctx->u.arcfour_ctx, len, plain, crypt); 457e5b75505Sopenharmony_ci break; 458e5b75505Sopenharmony_ci default: 459e5b75505Sopenharmony_ci return -1; 460e5b75505Sopenharmony_ci } 461e5b75505Sopenharmony_ci 462e5b75505Sopenharmony_ci return 0; 463e5b75505Sopenharmony_ci} 464e5b75505Sopenharmony_ci 465e5b75505Sopenharmony_ci 466e5b75505Sopenharmony_civoid crypto_cipher_deinit(struct crypto_cipher *ctx) 467e5b75505Sopenharmony_ci{ 468e5b75505Sopenharmony_ci bin_clear_free(ctx, sizeof(*ctx)); 469e5b75505Sopenharmony_ci} 470