1 #include <Rinternals.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <openssl/pem.h>
5 #include <openssl/hmac.h>
6 #include "utils.h"
7 
8 /***
9  * example from: https://wiki.openssl.org/index.php/EVP_Key_Agreement
10  *
11  *
12  */
13 
14 
R_diffie_hellman(SEXP key,SEXP peerkey)15 SEXP R_diffie_hellman(SEXP key, SEXP peerkey){
16   BIO *mem = BIO_new_mem_buf(RAW(key), LENGTH(key));
17   EVP_PKEY *pkey = d2i_PrivateKey_bio(mem, NULL);
18   BIO_free(mem);
19   bail(!!pkey);
20   EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
21   bail(!!ctx);
22   const unsigned char *ptr = RAW(peerkey);
23   EVP_PKEY *pubkey = d2i_PUBKEY(NULL, &ptr, LENGTH(peerkey));
24   bail(!!pubkey);
25   bail(EVP_PKEY_derive_init(ctx) > 0);
26   bail(EVP_PKEY_derive_set_peer(ctx, pubkey) > 0);
27 
28   /* Determine buffer length */
29   size_t skeylen = 0;
30   bail(EVP_PKEY_derive(ctx, NULL, &skeylen) > 0);
31   SEXP out = allocVector(RAWSXP, skeylen);
32   bail(EVP_PKEY_derive(ctx, RAW(out), &skeylen) > 0);
33 
34   /* cleanup */
35   EVP_PKEY_CTX_free(ctx);
36   EVP_PKEY_free(pkey);
37   EVP_PKEY_free(pubkey);
38   return out;
39 }
40