Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5f2c45e

Browse filesBrowse files
committed
kcapi: Enable offloading HS algs to kcapi
Linux Kernel Crypto API At some point I'd like to make use of kcapi to store keys for persistent crypto ops. Signed-off-by: Ben Collins <bcollins@libjwt.io>
1 parent e5f0079 commit 5f2c45e
Copy full SHA for 5f2c45e

File tree

Expand file treeCollapse file tree

2 files changed

+79
-4
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+79
-4
lines changed

‎CMakeLists.txt

Copy file name to clipboardExpand all lines: CMakeLists.txt
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ option(WITH_GNUTLS "Whether to use GnuTLS (default is auto detect)" ON)
3939
option(WITH_MBEDTLS "Whether to use mbedTLS (default is OFF)" OFF)
4040
option(WITH_LIBCURL "Whether to include CUrl for retrieving JWKS (default is OFF)" OFF)
4141
option(WITH_TESTS "Whether to build and run the testsuite (default is ON)" ON)
42+
option(WITH_KCAPI_MD "Whether to use the Linux Kernel Crypto API to offload hmac (default OFF)" OFF)
4243

4344
# Optional
4445
if (WITH_GNUTLS)
@@ -57,6 +58,10 @@ if (WITH_LIBCURL)
5758
pkg_check_modules(LIBCURL libcurl>=8.0.0 IMPORTED_TARGET REQUIRED)
5859
endif()
5960

61+
if (WITH_KCAPI_MD)
62+
find_library(HAVE_KCAPI kcapi REQUIRED)
63+
endif()
64+
6065
# Required
6166
pkg_check_modules(OPENSSL openssl>=3.0.0 IMPORTED_TARGET
6267
REQUIRED)
@@ -67,6 +72,12 @@ set_target_properties(jwt_static PROPERTIES
6772
OUTPUT_NAME jwt
6873
COMPILE_FLAGS -DJWT_STATIC_DEFINE)
6974

75+
if (HAVE_KCAPI)
76+
target_link_libraries(jwt PRIVATE kcapi)
77+
target_link_libraries(jwt_static PRIVATE kcapi)
78+
add_definitions(-DUSE_KCAPI_MD)
79+
endif()
80+
7081
add_custom_command(
7182
OUTPUT jwt-builder.i
7283
COMMAND ${CMAKE_C_COMPILER} -E ${CMAKE_SOURCE_DIR}/libjwt/jwt-common.c -DJWT_BUILDER

‎libjwt/jwt.c

Copy file name to clipboardExpand all lines: libjwt/jwt.c
+68-4Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212

1313
#include <jwt.h>
1414

15+
#ifdef USE_KCAPI_MD
16+
#include <kcapi.h>
17+
#define KCAPI_MAX_MD_SIZE 64
18+
#endif
19+
1520
/* https://github.com/zhicheng/base64 */
1621
#include "base64.h"
1722

@@ -333,6 +338,67 @@ static int __check_key_bits(jwt_t *jwt)
333338
return 1; // LCOV_EXCL_LINE
334339
}
335340

341+
static int sign_sha_hmac(jwt_t *jwt, char **out, unsigned int *len,
342+
const char *str, unsigned int str_len)
343+
{
344+
#ifdef USE_KCAPI_MD
345+
static int skip_kcapi = 0;
346+
size_t key_len;
347+
void *key;
348+
int ret;
349+
350+
/* If kcapi fails once, we don't try again. */
351+
if (skip_kcapi)
352+
goto fallback_ops; // LCOV_EXCL_LINE
353+
354+
key = jwt->key->oct.key;
355+
key_len = jwt->key->oct.len;
356+
357+
*out = jwt_malloc(KCAPI_MAX_MD_SIZE);
358+
if (*out == NULL)
359+
return 1; // LCOV_EXCL_LINE
360+
361+
switch (jwt->alg) {
362+
/* HMAC */
363+
case JWT_ALG_HS256:
364+
ret = kcapi_md_hmac_sha256(key, key_len, (uint8_t *)str,
365+
str_len, (uint8_t *)*out,
366+
KCAPI_MAX_MD_SIZE);
367+
break;
368+
case JWT_ALG_HS384:
369+
ret = kcapi_md_hmac_sha384(key, key_len, (uint8_t *)str,
370+
str_len, (uint8_t *)*out,
371+
KCAPI_MAX_MD_SIZE);
372+
break;
373+
case JWT_ALG_HS512:
374+
ret = kcapi_md_hmac_sha512(key, key_len, (uint8_t *)str,
375+
str_len, (uint8_t *)*out,
376+
KCAPI_MAX_MD_SIZE);
377+
break;
378+
// LCOV_EXCL_START
379+
default:
380+
/* This isn't a failure in kcapi, so just error out */
381+
jwt_freemem(out);
382+
return 1;
383+
// LCOV_EXCL_STOP
384+
}
385+
386+
if (ret > 0) {
387+
*len = ret;
388+
return 0;
389+
}
390+
391+
/* Fallthrough to normal ops */
392+
// LCOV_EXCL_START
393+
jwt_freemem(*out);
394+
skip_kcapi = 1;
395+
// LCOV_EXCL_STOP
396+
397+
fallback_ops:
398+
#endif
399+
return jwt_ops->sign_sha_hmac(jwt, out, len, str, str_len);
400+
}
401+
336402
int jwt_sign(jwt_t *jwt, char **out, unsigned int *len, const char *str,
337403
unsigned int str_len)
338404
{
@@ -343,7 +409,7 @@ int jwt_sign(jwt_t *jwt, char **out, unsigned int *len, const char *str,
343409
case JWT_ALG_HS512:
344410
if (__check_hmac(jwt))
345411
return 1;
346-
if (jwt_ops->sign_sha_hmac(jwt, out, len, str, str_len)) {
412+
if (sign_sha_hmac(jwt, out, len, str, str_len)) {
347413
/* There's not really a way to induce failure here,
348414
* and there's not really much of a chance this can fail
349415
* other than an internal fatal error in the crypto
@@ -415,7 +481,7 @@ jwt_t *jwt_verify_sig(jwt_t *jwt, const char *head, unsigned int head_len,
415481
const char *sig_b64)
416482
{
417483
int sig_len;
418-
unsigned char *sig = NULL;
484+
char_auth *sig = NULL;
419485

420486
switch (jwt->alg) {
421487
/* HMAC */
@@ -455,8 +521,6 @@ jwt_t *jwt_verify_sig(jwt_t *jwt, const char *head, unsigned int head_len,
455521

456522
if (jwt_ops->verify_sha_pem(jwt, head, head_len, sig, sig_len))
457523
jwt_write_error(jwt, "Token failed verification");
458-
459-
jwt_freemem(sig);
460524
break;
461525

462526
/* You wut, mate? */

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.