Permalink
Browse files

Use NIF instead of a driver for crypto functions

  • Loading branch information...
1 parent a49f454 commit 9e7cc2d7f6e6a74a690c139c427fe2ff71365d72 @zinid zinid committed Jun 2, 2013
Showing with 271 additions and 232 deletions.
  1. +3 −0 Makefile
  2. +141 −0 c_src/sha.c
  3. +0 −120 c_src/sha_drv.c
  4. +9 −9 configure
  5. +2 −2 configure.ac
  6. +2 −2 rebar.config
  7. +1 −1 src/p1_tls.app.src
  8. +94 −91 src/sha.erl
  9. +18 −4 src/tls_app.erl
  10. +1 −3 src/tls_sup.erl
View
@@ -6,4 +6,7 @@ src:
clean:
rebar clean
+test:
+ rebar skip_deps=true eunit
+
.PHONY: clean src
View
@@ -0,0 +1,141 @@
+#include <erl_nif.h>
+#include <string.h>
+#include <stdio.h>
+#include <openssl/sha.h>
+
+#define SHA1_T 1
+#define SHA224_T 224
+#define SHA256_T 256
+#define SHA384_T 384
+#define SHA512_T 512
+
+static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
+{
+ return 0;
+}
+
+static int convert(ErlNifEnv* env, int argc,
+ const ERL_NIF_TERM argv[],
+ int type, ErlNifBinary *out)
+{
+ ErlNifBinary in;
+ int res = 0;
+
+ if (argc == 1) {
+ if (enif_inspect_iolist_as_binary(env, argv[0], &in)) {
+ switch (type) {
+ case SHA1_T:
+ res = enif_alloc_binary(SHA_DIGEST_LENGTH, out);
+ if (res) SHA1(in.data, in.size, out->data);
+ break;
+ case SHA224_T:
+ res = enif_alloc_binary(SHA224_DIGEST_LENGTH, out);
+ if (res) SHA224(in.data, in.size, out->data);
+ break;
+ case SHA256_T:
+ res = enif_alloc_binary(SHA256_DIGEST_LENGTH, out);
+ if (res) SHA256(in.data, in.size, out->data);
+ break;
+ case SHA384_T:
+ res = enif_alloc_binary(SHA384_DIGEST_LENGTH, out);
+ if (res) SHA384(in.data, in.size, out->data);
+ break;
+ case SHA512_T:
+ res = enif_alloc_binary(SHA512_DIGEST_LENGTH, out);
+ if (res) SHA512(in.data, in.size, out->data);
+ break;
+ }
+ }
+ }
+
+ return res;
+}
+
+static ERL_NIF_TERM sha1(ErlNifEnv* env, int argc,
+ const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary out;
+
+ if (convert(env, argc, argv, SHA1_T, &out))
+ return enif_make_binary(env, &out);
+ else
+ return enif_make_badarg(env);
+}
+
+static ERL_NIF_TERM sha224(ErlNifEnv* env, int argc,
+ const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary out;
+
+ if (convert(env, argc, argv, SHA224_T, &out))
+ return enif_make_binary(env, &out);
+ else
+ return enif_make_badarg(env);
+}
+
+static ERL_NIF_TERM sha256(ErlNifEnv* env, int argc,
+ const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary out;
+
+ if (convert(env, argc, argv, SHA256_T, &out))
+ return enif_make_binary(env, &out);
+ else
+ return enif_make_badarg(env);
+}
+
+static ERL_NIF_TERM sha384(ErlNifEnv* env, int argc,
+ const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary out;
+
+ if (convert(env, argc, argv, SHA384_T, &out))
+ return enif_make_binary(env, &out);
+ else
+ return enif_make_badarg(env);
+}
+
+static ERL_NIF_TERM sha512(ErlNifEnv* env, int argc,
+ const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary out;
+
+ if (convert(env, argc, argv, SHA512_T, &out))
+ return enif_make_binary(env, &out);
+ else
+ return enif_make_badarg(env);
+}
+
+static ERL_NIF_TERM to_hexlist(ErlNifEnv* env, int argc,
+ const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary in;
+ ErlNifBinary out;
+ int res, i;
+
+ if (argc == 1) {
+ if (enif_inspect_iolist_as_binary(env, argv[0], &in)) {
+ res = enif_alloc_binary(2*in.size, &out);
+ if (res) {
+ for (i = 0; i<in.size; i++) {
+ sprintf((char *) (out.data + 2*i), "%02x", in.data[i]);
+ }
+ return enif_make_binary(env, &out);
+ }
+ }
+ }
+
+ return enif_make_badarg(env);
+}
+
+static ErlNifFunc nif_funcs[] =
+ {
+ {"sha1", 1, sha1},
+ {"sha224", 1, sha224},
+ {"sha256", 1, sha256},
+ {"sha384", 1, sha384},
+ {"sha512", 1, sha512},
+ {"to_hexlist", 1, to_hexlist}
+ };
+
+ERL_NIF_INIT(sha, nif_funcs, load, NULL, NULL, NULL)
View
@@ -1,120 +0,0 @@
-/*
- * ejabberd, Copyright (C) 2002-2013 ProcessOne
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- *
- */
-
-#include <erl_driver.h>
-#include <openssl/sha.h>
-#ifdef HAVE_MD2
-#include <openssl/md2.h>
-#endif
-
-/*
- * R15B changed several driver callbacks to use ErlDrvSizeT and
- * ErlDrvSSizeT typedefs instead of int.
- * This provides missing typedefs on older OTP versions.
- */
-#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2
-typedef int ErlDrvSizeT;
-typedef int ErlDrvSSizeT;
-#endif
-
-static ErlDrvData sha_drv_start(ErlDrvPort port, char *buf)
-{
- set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
- return NULL;
-}
-
-static ErlDrvSSizeT sha_drv_control(ErlDrvData handle,
- unsigned int command,
- char *buf, ErlDrvSizeT len,
- char **rbuf, ErlDrvSizeT rlen)
-{
- ErlDrvBinary *b = NULL;
-
- switch (command) {
-#ifdef HAVE_MD2
- case 2:
- rlen = MD2_DIGEST_LENGTH;
- b = driver_alloc_binary(rlen);
- if (b) MD2((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
- break;
-#endif
- case 224:
- rlen = SHA224_DIGEST_LENGTH;
- b = driver_alloc_binary(rlen);
- if (b) SHA224((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
- break;
- case 256:
- rlen = SHA256_DIGEST_LENGTH;
- b = driver_alloc_binary(rlen);
- if (b) SHA256((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
- break;
- case 384:
- rlen = SHA384_DIGEST_LENGTH;
- b = driver_alloc_binary(rlen);
- if (b) SHA384((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
- break;
- case 512:
- rlen = SHA512_DIGEST_LENGTH;
- b = driver_alloc_binary(rlen);
- if (b) SHA512((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
- break;
- };
-
- if (b) {
- *rbuf = (char *)b;
- } else {
- *rbuf = NULL;
- rlen = 0;
- };
-
- return rlen;
-}
-
-ErlDrvEntry sha_driver_entry = {
- NULL, /* F_PTR init, N/A */
- sha_drv_start, /* L_PTR start, called when port is opened */
- NULL, /* F_PTR stop, called when port is closed */
- NULL, /* F_PTR output, called when erlang has sent */
- NULL, /* F_PTR ready_input, called when input descriptor ready */
- NULL, /* F_PTR ready_output, called when output descriptor ready */
- "sha_drv", /* char *driver_name, the argument to open_port */
- NULL, /* F_PTR finish, called when unloaded */
- NULL, /* handle */
- sha_drv_control, /* F_PTR control, port_command callback */
- NULL, /* F_PTR timeout, reserved */
- NULL, /* F_PTR outputv, reserved */
- /* Added in Erlang/OTP R15B: */
- NULL, /* ready_async */
- NULL, /* flush */
- NULL, /* call */
- NULL, /* event */
- ERL_DRV_EXTENDED_MARKER, /* extended_marker */
- ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */
- ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */
- 0, /* driver_flags */
- NULL, /* handle2 */
- NULL, /* process_exit */
- NULL /* stop_select */
-};
-
-DRIVER_INIT(sha_drv) /* must match name in driver_entry */
-{
- return &sha_driver_entry;
-}
View
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67 for tls 0.1.0.
+# Generated by GNU Autoconf 2.67 for tls 0.2.0.
#
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -549,8 +549,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='tls'
PACKAGE_TARNAME='tls'
-PACKAGE_VERSION='0.1.0'
-PACKAGE_STRING='tls 0.1.0'
+PACKAGE_VERSION='0.2.0'
+PACKAGE_STRING='tls 0.2.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1202,7 +1202,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures tls 0.1.0 to adapt to many kinds of systems.
+\`configure' configures tls 0.2.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1263,7 +1263,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of tls 0.1.0:";;
+ short | recursive ) echo "Configuration of tls 0.2.0:";;
esac
cat <<\_ACEOF
@@ -1346,7 +1346,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-tls configure 0.1.0
+tls configure 0.2.0
generated by GNU Autoconf 2.67
Copyright (C) 2010 Free Software Foundation, Inc.
@@ -1644,7 +1644,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by tls $as_me 0.1.0, which was
+It was created by tls $as_me 0.2.0, which was
generated by GNU Autoconf 2.67. Invocation command line was
$ $0 $@
@@ -4367,7 +4367,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by tls $as_me 0.1.0, which was
+This file was extended by tls $as_me 0.2.0, which was
generated by GNU Autoconf 2.67. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -4411,7 +4411,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-tls config.status 0.1.0
+tls config.status 0.2.0
configured by $0, generated by GNU Autoconf 2.67,
with options \\"\$ac_cs_config\\"
View
@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.53)
-AC_PACKAGE_VERSION(0.1.0)
-AC_INIT(tls, 0.1.0, [], [])
+AC_PACKAGE_VERSION(0.2.0)
+AC_INIT(tls, 0.2.0, [], [])
# Checks for programs.
AC_PROG_CC
View
@@ -1,10 +1,10 @@
{erl_opts, [debug_info]}.
-{port_env, [{"CFLAGS", "$CFLAGS -g -O2 -Wall"},
+{port_env, [{"CFLAGS", "$CFLAGS -ggdb -Wall"},
{"LDFLAGS", "$LDFLAGS -lssl -lcrypto"}]}.
{port_specs, [{"priv/lib/tls_drv.so", ["c_src/tls_drv.c"]},
- {"priv/lib/sha_drv.so", ["c_src/sha_drv.c"]}]}.
+ {"priv/lib/sha.so", ["c_src/sha.c"]}]}.
%% Local Variables:
%% mode: erlang
View
@@ -8,7 +8,7 @@
%%%-------------------------------------------------------------------
{application, p1_tls,
[{description, "OpenSSL wrapper"},
- {vsn, "0.1.0"},
+ {vsn, "0.2.0"},
{modules, []},
{registered, []},
{applications, [kernel, stdlib]},
Oops, something went wrong.

0 comments on commit 9e7cc2d

Please sign in to comment.