Skip to content

Commit

Permalink
Add mbedtls support
Browse files Browse the repository at this point in the history
based on the work of Rockyshen123 (pull#66)
  • Loading branch information
paolostivanin committed Oct 4, 2024
1 parent 9b3601c commit 248bd66
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 18 deletions.
49 changes: 42 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ jobs:
- checkout
- run:
command: |
export DEBIAN_FRONTEND=noninteractive
apt update && apt -y install git gcc clang cmake libcriterion-dev libgcrypt20-dev
mkdir build && cd "$_"
cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTS=ON ..
make && make install
./tests/test_base32encode
./tests/test_base32decode
./tests/test_cotp
ubuntu2204_gcrypt:
ubuntu2404_gcrypt:
docker:
- image: ubuntu:22.04
- image: ubuntu:24.04
steps:
- checkout
- run:
command: |
export DEBIAN_FRONTEND=noninteractive
apt update && apt -y install git gcc clang cmake libcriterion-dev libgcrypt20-dev
mkdir build && cd "$_"
cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTS=ON ..
Expand All @@ -36,33 +38,66 @@ jobs:
- checkout
- run:
command: |
export DEBIAN_FRONTEND=noninteractive
apt update && apt -y install git gcc clang cmake libcriterion-dev libssl-dev
mkdir build && cd "$_"
cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTS=ON -DHMAC_WRAPPER=openssl ..
make && make install
./tests/test_base32encode
./tests/test_base32decode
./tests/test_cotp
ubuntu2204_openssl:
ubuntu2404_openssl:
docker:
- image: ubuntu:22.04
- image: ubuntu:24.04
steps:
- checkout
- run:
command: |
export DEBIAN_FRONTEND=noninteractive
apt update && apt -y install git gcc clang cmake libcriterion-dev libssl-dev
mkdir build && cd "$_"
cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTS=ON -DHMAC_WRAPPER=openssl ..
make && make install
./tests/test_base32encode
./tests/test_base32decode
./tests/test_cotp
debianStable_mbedtls:
docker:
- image: debian:stable
steps:
- checkout
- run:
command: |
export DEBIAN_FRONTEND=noninteractive
apt update && apt -y install git gcc clang cmake libcriterion-dev libmbedtls-dev
mkdir build && cd "$_"
cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTS=ON -DHMAC_WRAPPER=mbedtls ..
make && make install
./tests/test_base32encode
./tests/test_base32decode
./tests/test_cotp
ubuntu2404_mbedtls:
docker:
- image: ubuntu:24.04
steps:
- checkout
- run:
command: |
export DEBIAN_FRONTEND=noninteractive
apt update && apt -y install git gcc clang cmake libcriterion-dev libmbedtls-dev
mkdir build && cd "$_"
cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTS=ON -DHMAC_WRAPPER=mbedtls ..
make && make install
./tests/test_base32encode
./tests/test_base32decode
./tests/test_cotp
workflows:
version: 2
build:
jobs:
- debianStable_gcrypt
- ubuntu2204_gcrypt
- ubuntu2404_gcrypt
- debianStable_openssl
- ubuntu2204_openssl
- ubuntu2404_openssl
- debianStable_mbedtls
- ubuntu2404_mbedtls
16 changes: 11 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ find_package(PkgConfig)

option(BUILD_SHARED_LIBS "Build libcotp as a shared library" ON)
option(BUILD_TESTS "Build base32 and cotp tests" OFF)
set(HMAC_WRAPPER "gcrypt" CACHE STRING "Choose between gcrypt (default), openssl or mbedtls for HMAC computation")
set_property(CACHE HMAC_WRAPPER PROPERTY STRINGS "gcrypt" "openssl" "mbedtls")

set(HMAC_WRAPPER "gcrypt" CACHE STRING "library to use during hmac computation")
if("${HMAC_WRAPPER}" STREQUAL "gcrypt")
set(HMAC_SOURCE_FILES
src/utils/whmac_gcrypt.c
)
find_package(Gcrypt 1.8.0 REQUIRED)
set(HMAC_INCLUDE_DIR ${GCRYPT_INCLUDE_DIR})
set(HMAC_LIBRARY_DIRS ${GCRYPT_LIBRARY_DIRS})
set(HMAC_LIBRARIES ${GCRYPT_LIBRARIES})
message("libcotp will use gcrypt for hmac")
elseif("${HMAC_WRAPPER}" STREQUAL "openssl")
Expand All @@ -28,15 +28,21 @@ elseif("${HMAC_WRAPPER}" STREQUAL "openssl")
src/utils/whmac_openssl.c
)
set(HMAC_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR})
set(HMAC_LIBRARY_DIRS ${OPENSSL_LIBRARY_DIRS})
set(HMAC_LIBRARIES ${OPENSSL_LIBRARIES})
message("libcotp will use openssl for hmac")
elseif("${HMAC_WRAPPER}" STREQUAL "mbedtls")
find_package(MbedTLS REQUIRED)
set(HMAC_SOURCE_FILES
src/utils/whmac_mbedtls.c
)
set(HMAC_INCLUDE_DIR ${MBEDTLS_INCLUDE_DIRS})
set(HMAC_LIBRARIES ${MBEDTLS_LIBRARIES})
message("libcotp will use mbedtls for hmac")
else()
message("libcotp can't use ${HMAC_WRAPPER} for hmac")
endif()

include_directories(${HMAC_INCLUDE_DIR})
link_directories(${HMAC_LIBRARY_DIRS})

if (BUILD_TESTS)
add_subdirectory(tests)
Expand Down Expand Up @@ -109,4 +115,4 @@ if (PkgConfig_FOUND)

configure_file("cotp.pc.in" "cotp.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/cotp.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig/)
endif()
endif()
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ C library that generates TOTP and HOTP according to [RFC-6238](https://tools.iet

## Requirements
- GCC/Clang and CMake to build the library
- libgcrypt >= 1.8.0 or openssl >= 3.0.0
- libgcrypt >= 1.8.0 or openssl >= 3.0.0 or mbedtls (works with both 2.x and 3.x)

## Build and Install
```
Expand All @@ -17,13 +17,13 @@ $ cd libcotp
$ mkdir build && cd $_
$ cmake -DCMAKE_INSTALL_PREFIX=/usr ..
$ make
# make install
$ sudo make install
```

Available options you can pass to `cmake`:
* `-DBUILD_TESTS=ON`: if you want to compile also the tests (default **OFF**, requires criterion)
* `-DBUILD_SHARED_LIBS=ON`: if you want to build libcotp as a shared library (default **ON**)
* `-DHMAC_WRAPPER="<gcrypt|openssl>"`: you can choose between GCrypt and OpenSSL (default **Gcrypt**)
* `-DBUILD_SHARED_LIBS=OFF`: if you want to build libcotp as a static library (default **ON**)
* `-DHMAC_WRAPPER="<gcrypt|openssl|mbedtls>"`: you can choose between GCrypt, OpenSSL or MbedTLS (default **Gcrypt**)

## How To Use It
```
Expand Down
111 changes: 111 additions & 0 deletions cmake/FindMbedTLS.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) Daniel Stenberg, <[email protected]>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
# Find the mbedtls library
#
# Input variables:
#
# MBEDTLS_INCLUDE_DIR The mbedtls include directory
# MBEDTLS_INCLUDE_DIRS The mbedtls include directory (deprecated)
# MBEDTLS_LIBRARY Path to mbedtls library
# MBEDX509_LIBRARY Path to mbedx509 library
# MBEDCRYPTO_LIBRARY Path to mbedcrypto library
#
# Result variables:
#
# MBEDTLS_FOUND System has mbedtls
# MBEDTLS_INCLUDE_DIRS The mbedtls include directories
# MBEDTLS_LIBRARIES The mbedtls library names
# MBEDTLS_VERSION Version of mbedtls

if(DEFINED MBEDTLS_INCLUDE_DIRS AND NOT DEFINED MBEDTLS_INCLUDE_DIR)
message(WARNING "MBEDTLS_INCLUDE_DIRS is deprecated, use MBEDTLS_INCLUDE_DIR instead.")
set(MBEDTLS_INCLUDE_DIR "${MBEDTLS_INCLUDE_DIRS}")
unset(MBEDTLS_INCLUDE_DIRS)
endif()

if(CURL_USE_PKGCONFIG)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_MBEDTLS "mbedtls")
endif()

find_path(MBEDTLS_INCLUDE_DIR NAMES "mbedtls/ssl.h"
HINTS
${PC_MBEDTLS_INCLUDEDIR}
${PC_MBEDTLS_INCLUDE_DIRS}
)

find_library(MBEDTLS_LIBRARY NAMES "mbedtls"
HINTS
${PC_MBEDTLS_LIBDIR}
${PC_MBEDTLS_LIBRARY_DIRS}
)
find_library(MBEDX509_LIBRARY NAMES "mbedx509"
HINTS
${PC_MBEDTLS_LIBDIR}
${PC_MBEDTLS_LIBRARY_DIRS}
)
find_library(MBEDCRYPTO_LIBRARY NAMES "mbedcrypto"
HINTS
${PC_MBEDTLS_LIBDIR}
${PC_MBEDTLS_LIBRARY_DIRS}
)

if(PC_MBEDTLS_VERSION)
set(MBEDTLS_VERSION ${PC_MBEDTLS_VERSION})
elseif(MBEDTLS_INCLUDE_DIR)
if(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h") # 3.x
set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")
elseif(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h") # 2.x
set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")
else()
unset(_version_header)
endif()
if(_version_header)
set(_version_regex "#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"([0-9.]+)\"")
file(STRINGS "${_version_header}" _version_str REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
set(MBEDTLS_VERSION "${_version_str}")
unset(_version_regex)
unset(_version_str)
unset(_version_header)
endif()
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MbedTLS
REQUIRED_VARS
MBEDTLS_INCLUDE_DIR
MBEDTLS_LIBRARY
MBEDX509_LIBRARY
MBEDCRYPTO_LIBRARY
VERSION_VAR
MBEDTLS_VERSION
)

if(MBEDTLS_FOUND)
set(MBEDTLS_INCLUDE_DIRS ${MBEDTLS_INCLUDE_DIR})
set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
endif()

mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
94 changes: 94 additions & 0 deletions src/utils/whmac_mbedtls.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>
#include <mbedtls/md.h>
#include "../whmac.h"
#include "../cotp.h"

typedef struct whmac_handle_s whmac_handle_t;

struct whmac_handle_s
{
mbedtls_md_context_t sha_ctx;
const mbedtls_md_info_t *md_info;
int algo;
size_t dlen;
};

int
whmac_check (void)
{
return 0;
}

size_t
whmac_getlen (whmac_handle_t *hd)
{
return mbedtls_md_get_size(hd->md_info);
}

whmac_handle_t *
whmac_gethandle (int algo)
{
const mbedtls_md_type_t openssl_algo[] = {
MBEDTLS_MD_SHA1,
MBEDTLS_MD_SHA256,
MBEDTLS_MD_SHA512,
};

whmac_handle_t *whmac_handle = calloc (1, sizeof(*whmac_handle));
if (whmac_handle == NULL) {
return NULL;
}

if (algo > 2) {
free (whmac_handle);
return NULL;
}

mbedtls_md_init (&(whmac_handle->sha_ctx));
whmac_handle->md_info = mbedtls_md_info_from_type (openssl_algo[algo]);
int ret = mbedtls_md_setup (&(whmac_handle->sha_ctx), whmac_handle->md_info, 1);
if (ret != 0) {
printf ("mbedtls_md_setup() returned -0x%04x\n", -ret);
mbedtls_md_free (&(whmac_handle->sha_ctx));
free (whmac_handle);
return NULL;
}

return whmac_handle;
}

void
whmac_freehandle (whmac_handle_t *hd)
{
mbedtls_md_free (&(hd->sha_ctx));
free (hd);
}

int
whmac_setkey (whmac_handle_t *hd,
unsigned char *buffer,
size_t buflen)
{
mbedtls_md_hmac_starts (&(hd->sha_ctx), buffer, buflen);
return NO_ERROR;
}

void
whmac_update (whmac_handle_t *hd,
unsigned char *buffer,
size_t buflen)
{
mbedtls_md_hmac_update (&(hd->sha_ctx), buffer, buflen);
}

ssize_t
whmac_finalize (whmac_handle_t *hd,
unsigned char *buffer,
size_t buflen)
{
mbedtls_md_hmac_finish (&(hd->sha_ctx), buffer);

return buflen;
}

4 changes: 2 additions & 2 deletions src/utils/whmac_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ whmac_gethandle (int algo)

size_t params_n = 0;

whmac_handle->mac_params[params_n++] = OSSL_PARAM_construct_utf8_string("digest", (char *)openssl_algo[algo], 0);
whmac_handle->mac_params[params_n] = OSSL_PARAM_construct_end();
whmac_handle->mac_params[params_n++] = OSSL_PARAM_construct_utf8_string ("digest", (char *)openssl_algo[algo], 0);
whmac_handle->mac_params[params_n] = OSSL_PARAM_construct_end ();
}
return whmac_handle;
}
Expand Down

0 comments on commit 248bd66

Please sign in to comment.