/* Use openssl digest-functions in SQLite3
   Compile: gcc -Wall sqlite_hash.c -o hash.so -lcrypto -shared
   Load: .load hash.so
   Usage: select hash('sha256', 'Teststring') as ShaBlob;
          select hex(hash('sha256', 'Teststring')) as ShaString; */

#include <openssl/evp.h>
#include <sqlite3ext.h>
 
SQLITE_EXTENSION_INIT1
 
static void hashFunc(sqlite3_context *context, int argc, sqlite3_value **argv){

  EVP_MD_CTX mdctx;
  const EVP_MD *md;
  unsigned char md_value[EVP_MAX_MD_SIZE];
  unsigned int md_len;

 
  md = EVP_get_digestbyname(sqlite3_value_text(argv[0]));
  if(md==NULL){

    sqlite3_result_error(context,"Unknown hash-algorithm.",-1);
    return;
  }
 
  EVP_MD_CTX_init(&mdctx);

 
  EVP_DigestInit_ex(&mdctx, md, NULL);
  EVP_DigestUpdate(&mdctx, sqlite3_value_blob(argv[1]), sqlite3_value_bytes(argv[1]));
  EVP_DigestFinal_ex(&mdctx, md_value, &md_len);

 
  EVP_MD_CTX_cleanup(&mdctx);
 
  sqlite3_result_blob(context, md_value, md_len, SQLITE_TRANSIENT);

}
 
int sqlite3_extension_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi){

  SQLITE_EXTENSION_INIT2(pApi)
 
  OpenSSL_add_all_digests();
 
  sqlite3_create_function(db, "hash", 2, SQLITE_BLOB, 0, hashFunc, 0, 0);

 
  return 0;
}