-
-/* rfc 3447, appendix B.2 */
-static void mgf1(unsigned char *seed, size_t seed_len, unsigned result_len,
- unsigned char *result)
-{
- gcry_error_t gret;
- gcry_md_hd_t handle;
- size_t n;;
- unsigned char *md;
- unsigned char octet_string[4], *rp = result, *end = rp + result_len;
-
- assert(result_len / HASH_SIZE < 1ULL << 31);
- gret = gcry_md_open(&handle, GCRY_MD_SHA1, 0);
- assert(gret == 0);
- for (n = 0; rp < end; n++) {
- gcry_md_write(handle, seed, seed_len);
- octet_string[0] = (unsigned char)((n >> 24) & 255);
- octet_string[1] = (unsigned char)((n >> 16) & 255);
- octet_string[2] = (unsigned char)((n >> 8)) & 255;
- octet_string[3] = (unsigned char)(n & 255);
- gcry_md_write(handle, octet_string, 4);
- gcry_md_final(handle);
- md = gcry_md_read(handle, GCRY_MD_SHA1);
- memcpy(rp, md, PARA_MIN(HASH_SIZE, (int)(end - rp)));
- rp += HASH_SIZE;
- gcry_md_reset(handle);
- }
- gcry_md_close(handle);
-}
-
-/** The sha1 hash of an empty file. */
-static const unsigned char empty_hash[HASH_SIZE] =
- "\xda" "\x39" "\xa3" "\xee" "\x5e"
- "\x6b" "\x4b" "\x0d" "\x32" "\x55"
- "\xbf" "\xef" "\x95" "\x60" "\x18"
- "\x90" "\xaf" "\xd8" "\x07" "\x09";
-
-/* rfc3447, section 7.1.1 */
-static void pad_oaep(unsigned char *in, size_t in_len, unsigned char *out,
- size_t out_len)
-{
- size_t ps_len = out_len - in_len - 2 * HASH_SIZE - 2;
- size_t n, mask_len = out_len - HASH_SIZE - 1;
- unsigned char *seed = out + 1, *db = seed + HASH_SIZE,
- *ps = db + HASH_SIZE, *one = ps + ps_len;
- unsigned char *db_mask, seed_mask[HASH_SIZE];
-
- assert(in_len <= out_len - 2 - 2 * HASH_SIZE);
- assert(out_len > 2 * HASH_SIZE + 2);
- PARA_DEBUG_LOG("padding %zu byte input -> %zu byte output\n",
- in_len, out_len);
- dump_buffer("unpadded buffer", in, in_len);
-
- out[0] = '\0';
- get_random_bytes_or_die(seed, HASH_SIZE);
- memcpy(db, empty_hash, HASH_SIZE);
- memset(ps, 0, ps_len);
- *one = 0x01;
- memcpy(one + 1, in, in_len);
- db_mask = para_malloc(mask_len);
- mgf1(seed, HASH_SIZE, mask_len, db_mask);
- for (n = 0; n < mask_len; n++)
- db[n] ^= db_mask[n];
- mgf1(db, mask_len, HASH_SIZE, seed_mask);
- for (n = 0; n < HASH_SIZE; n++)
- seed[n] ^= seed_mask[n];
- free(db_mask);
- dump_buffer("padded buffer", out, out_len);
-}
-
-/* rfc 3447, section 7.1.2 */
-static int unpad_oaep(unsigned char *in, size_t in_len, unsigned char *out,
- size_t *out_len)
-{
- unsigned char *masked_seed = in + 1;
- unsigned char *db = in + 1 + HASH_SIZE;
- unsigned char seed[HASH_SIZE], seed_mask[HASH_SIZE];
- unsigned char *db_mask, *p;
- size_t n, mask_len = in_len - HASH_SIZE - 1;
-
- mgf1(db, mask_len, HASH_SIZE, seed_mask);
- for (n = 0; n < HASH_SIZE; n++)
- seed[n] = masked_seed[n] ^ seed_mask[n];
- db_mask = para_malloc(mask_len);
- mgf1(seed, HASH_SIZE, mask_len, db_mask);
- for (n = 0; n < mask_len; n++)
- db[n] ^= db_mask[n];
- free(db_mask);
- if (memcmp(db, empty_hash, HASH_SIZE))
- return -E_OEAP;
- for (p = db + HASH_SIZE; p < in + in_len - 1; p++)
- if (*p != '\0')
- break;
- if (p >= in + in_len - 1)
- return -E_OEAP;
- p++;
- *out_len = in + in_len - p;
- memcpy(out, p, *out_len);
- return 1;
-}