- int ret;
- gcry_error_t gret;
- unsigned char oaep_buf[512];
- gcry_mpi_t out_mpi;
-
- if (libgcrypt_has_oaep) {
- const char *p = gcry_sexp_nth_data(sexp, 1, nbytes);
-
- if (!p) {
- PARA_ERROR_LOG("could not get data from list\n");
- return -E_OEAP;
- }
- memcpy(outbuf, p, *nbytes);
- return 1;
- }
- out_mpi = gcry_sexp_nth_mpi(sexp, 0, GCRYMPI_FMT_USG);
- if (!out_mpi)
- return -E_SEXP_FIND;
- gret = gcry_mpi_print(GCRYMPI_FMT_USG, oaep_buf, sizeof(oaep_buf),
- nbytes, out_mpi);
- if (gret) {
- PARA_ERROR_LOG("mpi_print: %s\n", gcrypt_strerror(gret));
- ret = -E_MPI_PRINT;
- goto out_mpi_release;
- }
- /*
- * An oaep-encoded buffer always starts with at least one zero byte.
- * However, leading zeroes in an mpi are omitted in the output of
- * gcry_mpi_print() when using the GCRYMPI_FMT_USG format. The
- * alternative, GCRYMPI_FMT_STD, does not work either because here the
- * leading zero(es) might also be omitted, depending on the value of
- * the second byte.
- *
- * To circumvent this, we shift the oaep buffer to the right. But first
- * we check that the buffer actually started with a zero byte, i.e. that
- * nbytes < key_size. Otherwise a decoding error occurred.
- */
- ret = -E_SEXP_DECRYPT;
- if (*nbytes >= key_size)
- goto out_mpi_release;
- memmove(oaep_buf + key_size - *nbytes, oaep_buf, *nbytes);
- memset(oaep_buf, 0, key_size - *nbytes);