title: How can add my own hash(digest) algorithm to openssl
body: <p>I want to use my own hash algorithm in openvpn config. I think I should define it in openssl (library), and I look at MD5 algorithm as an example to see how it is defined. I did something like what is done for MD5 but my algorithm isn't added yet! I check this using command "openvpn --show-digests". can you refer me to some document about this?I added "m_myhash.c" in crypto/evp/m_myhash.c (like m_md5.c) </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include "cryptlib.h"
  
  #ifndef OPENSSL_NO_MD5
  
  # include &lt;openssl/evp.h&gt;
  # include &lt;openssl/objects.h&gt;
  # include &lt;openssl/x509.h&gt;
  # include &lt;openssl/md5.h&gt;
  # ifndef OPENSSL_NO_RSA
  #  include &lt;openssl/rsa.h&gt;
  # endif
  # include "evp_locl.h"
  
  static int init(EVP_MD_CTX *ctx)
  {
      return MD5_Init(ctx-&gt;md_data);
  }
  
  static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
  {
      return MD5_Update(ctx-&gt;md_data, data, count);
  }
  
  static int final(EVP_MD_CTX *ctx, unsigned char *md)
  {
      return MD5_Final(md, ctx-&gt;md_data);
  }
  
  static const EVP_MD myhash_md = {
      NID_md5,
      NID_md5WithRSAEncryption,
      MD5_DIGEST_LENGTH,
      0,
      init,
      update,
      final,
      NULL,
      NULL,
      EVP_PKEY_RSA_method,
      MD5_CBLOCK,
      sizeof(EVP_MD *) + sizeof(MD5_CTX),
  };
  
  const EVP_MD *EVP_myhash(void)
  {
      return (&amp;myhash_md);
  }
  #endif
  </code></pre>
  
  <p>I did not changed functions already, I used md5's functions.(I want to understand defining a new hash algorithm how and where should be done and be compiled, so for now I use md5's init,update, ...) </p>
  
  <p>I added lines to crypto/evp/Makefile to compile m_myhash.c and its object file is produced.</p>
  
  <p>then I added this <code>EVP_add_digest(EVP_myhash());</code></p>
  
  <pre><code>void OpenSSL_add_all_digests(void)
  {
  #ifndef OPENSSL_NO_MD4
      EVP_add_digest(EVP_md4());
  #endif
  #ifndef OPENSSL_NO_MD5
      EVP_add_digest(EVP_md5());
      EVP_add_digest_alias(SN_md5, "ssl2-md5");
      EVP_add_digest_alias(SN_md5, "ssl3-md5");
      EVP_add_digest(EVP_myhash());
  #endif
    ...
  }
  </code></pre>
  
  <p>to this file <code>crypto/evp/c_alld.c</code>.</p>
  
  <p>I added this </p>
  
  <pre><code>#define SN_myhash          "MYHASH"
  #define LN_myhash          "myhash"
  #define NID_myhash         920
  #define OBJ_myhash         OBJ_rsadsi,2L,5L
  </code></pre>
  
  <p>to file <code>crypto/evp/c_alld.c</code>. (here also last line is same as md5,I'm not sure about this!)</p>
  
  <p>I added 
  <code>920,    /* OBJ_gholi                        1 2 840 113549 2 5 */</code></p>
  
  <p>I added this line</p>
  
  <pre><code>920,    /* OBJ_gholi                        1 2 840 113549 2 5 */
  </code></pre>
  
  <p>to file <code>crypto/objects/obj_dat.h</code></p>
  
  <p>I added <code>{"MYHASH","myhash",NID_myhash,8,&amp;(lvalues[5973]),0},</code> to this structure in file <code>crypto/objects/obj_dat.h</code></p>
  
  <pre><code>static const ASN1_OBJECT nid_objs[NUM_NID]={
  {"UNDEF","undefined",NID_undef,0,NULL,0},
  {"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&amp;(lvalues[0]),0},
  {"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&amp;(lvalues[6]),0},
  {"MD2","md2",NID_md2,8,&amp;(lvalues[13]),0},
  {"MD5","md5",NID_md5,8,&amp;(lvalues[21]),0},
  {"MYHASH","myhash",NID_myhash,8,&amp;(lvalues[5973]),0},
  {"RC4","rc4",NID_rc4,8,&amp;(lvalues[29]),0},
  </code></pre>
  
  <p>...
  }</p>
  
  <p>I added this
   <code>gholi                   920</code>
  to file <code>crypto/objects/obj_mac.num</code></p>
  
  <p>also added </p>
  
  <pre><code>const EVP_MD *EVP_gholi(void);
  </code></pre>
  
  <p>to file <code>crypto/evp/evp.h</code></p>
  
  <p>I'm completely new to openssl code, I'm pretty sure I may have done blind and stupid things, sorry for that!</p>