]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
OSSL_FN: Add internal construction and introspection functions
authorRichard Levitte <levitte@openssl.org>
Wed, 22 Oct 2025 13:50:41 +0000 (15:50 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 11 Dec 2025 09:35:45 +0000 (10:35 +0100)
These functions will be useful with other test programs without having
to include crypto/fn/fn_local.h, making them closer to real world use.

This also introduces OSSL_FN errors

Related-to: doc/designs/fixed-size-large-numbers.md
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29028)

crypto/err/err_all.c
crypto/err/openssl.ec
crypto/err/openssl.txt
crypto/fn/build.info
crypto/fn/fn_err.c [new file with mode: 0644]
crypto/fn/fn_intern.c [new file with mode: 0644]
crypto/fn/fn_local.h
include/crypto/fn_intern.h [new file with mode: 0644]
include/crypto/fnerr.h [new file with mode: 0644]
include/openssl/err.h.in
test/fn_internal_test.c

index be3d91280aed75bc71690de35a9eb1442d575ed9..6955d7d22bf45dc8755fba9f6f517929c361821a 100644 (file)
@@ -13,6 +13,7 @@
 #include "crypto/cryptoerr.h"
 #include "crypto/asn1err.h"
 #include "crypto/bnerr.h"
+#include "crypto/fnerr.h"
 #include "crypto/ecerr.h"
 #include "crypto/buffererr.h"
 #include "crypto/bioerr.h"
@@ -50,6 +51,7 @@ int ossl_err_load_crypto_strings(void)
 #ifndef OPENSSL_NO_ERR
         || ossl_err_load_ERR_strings() == 0 /* include error strings for SYSerr */
         || ossl_err_load_BN_strings() == 0
+        || ossl_err_load_OSSL_FN_strings() == 0
         || ossl_err_load_RSA_strings() == 0
 #ifndef OPENSSL_NO_DH
         || ossl_err_load_DH_strings() == 0
index a3fce49548989c19ee6f3a8f352557bf9ce4af94..db4e40fe1a1927c72acc6fc4dc80aa4073463ba0 100644 (file)
@@ -43,6 +43,7 @@ L PROV          include/openssl/proverr.h       providers/common/provider_err.c
 L OSSL_ENCODER  include/openssl/encodererr.h    crypto/encode_decode/encoder_err.c      include/crypto/encodererr.h
 L OSSL_DECODER  include/openssl/decodererr.h    crypto/encode_decode/decoder_err.c      include/crypto/decodererr.h
 L HTTP          include/openssl/httperr.h       crypto/http/http_err.c                  include/crypto/httperr.h
+L OSSL_FN       NONE                            crypto/fn/fn_err.c                      include/crypto/fnerr.h
 
 # SSL/TLS alerts
 R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE          1010
index 70e06a6a38aed05a9eeb6864c2eb2dcc1bd4042f..4acda0f0a5d42a77a798be35c45e6eccae9c01c7 100644 (file)
@@ -884,6 +884,7 @@ OSSL_DECODER_R_MISSING_GET_PARAMS:100:missing get params
 OSSL_ENCODER_R_ENCODER_NOT_FOUND:101:encoder not found
 OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query
 OSSL_ENCODER_R_MISSING_GET_PARAMS:102:missing get params
+OSSL_FN_R_RESULT_ARG_TOO_SMALL:100:result arg too small
 OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type
 OSSL_STORE_R_BAD_PASSWORD_READ:115:bad password read
 OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC:113:error verifying pkcs12 mac
index 218e4b01e5c2a8328ef19eea65650e506ffbaaa9..694acce2e4d73a9f8857afaa2bbe17aa98e7d70b 100644 (file)
@@ -2,7 +2,7 @@ $LIBCRYPTO=../../libcrypto
 $LIBFIPS=../../providers/libfips.a
 LIBS=$LIBCRYPTO
 
-$COMMON=fn_lib.c
+$COMMON=fn_err.c fn_lib.c fn_intern.c
 
 SOURCE[$LIBCRYPTO]=$COMMON
 SOURCE[$LIBFIPS]=$COMMON
diff --git a/crypto/fn/fn_err.c b/crypto/fn/fn_err.c
new file mode 100644 (file)
index 0000000..bf6c147
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/err.h>
+#include "crypto/fnerr.h"
+
+#ifndef OPENSSL_NO_ERR
+
+static const ERR_STRING_DATA OSSL_FN_str_reasons[] = {
+    { ERR_PACK(ERR_LIB_OSSL_FN, 0, OSSL_FN_R_RESULT_ARG_TOO_SMALL),
+        "result arg too small" },
+    { 0, NULL }
+};
+
+#endif
+
+int ossl_err_load_OSSL_FN_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+    if (ERR_reason_error_string(OSSL_FN_str_reasons[0].error) == NULL)
+        ERR_load_strings_const(OSSL_FN_str_reasons);
+#endif
+    return 1;
+}
diff --git a/crypto/fn/fn_intern.c b/crypto/fn/fn_intern.c
new file mode 100644 (file)
index 0000000..3aa3afb
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/cryptlib.h"
+#include "crypto/fn_intern.h"
+#include "crypto/fnerr.h"
+#include "fn_local.h"
+#include <openssl/err.h>
+
+int ossl_fn_set_words(OSSL_FN *f, const OSSL_FN_ULONG *words, size_t limbs)
+{
+    if (ossl_unlikely(f == NULL)) {
+        ERR_raise(ERR_LIB_OSSL_FN, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if ((size_t)f->dsize < limbs) {
+        ERR_raise(ERR_LIB_OSSL_FN, OSSL_FN_R_RESULT_ARG_TOO_SMALL);
+        return 0;
+    }
+
+    memcpy(f->d, words, sizeof(OSSL_FN_ULONG) * limbs);
+    memset(f->d + limbs, 0, sizeof(OSSL_FN_ULONG) * (f->dsize - limbs));
+    return 1;
+}
+
+const OSSL_FN_ULONG *ossl_fn_get_words(OSSL_FN *f)
+{
+    if (ossl_unlikely(f == NULL)) {
+        ERR_raise(ERR_LIB_OSSL_FN, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+
+    return f->d;
+}
+
+size_t ossl_fn_get_dsize(OSSL_FN *f)
+{
+    return f->dsize;
+}
+
+bool ossl_fn_is_dynamically_allocated(OSSL_FN *f)
+{
+    return f->is_dynamically_allocated;
+}
+
+bool ossl_fn_is_securely_allocated(OSSL_FN *f)
+{
+    return f->is_securely_allocated;
+}
index 46b3e82b2697cbcb9b1f5b774ea2706c9336aa55..c30ab7230448c1205ffa3399906579915d0eda67 100644 (file)
 #include <openssl/e_os2.h>
 #include "internal/common.h"
 #include "crypto/fn.h"
+#include "crypto/fn_intern.h"
+
+#if OSSL_FN_BYTES == 4
+/* 32-bit systems */
+#define OSSL_FN_MASK UINT32_MAX
+#elif OSSL_FN_BYTES == 8
+/* 64-bit systems */
+#define OSSL_FN_MASK UINT64_MAX
+#else
+#error "OpenSSL doesn't support large numbers on this platform"
+#endif
+
+#define OSSL_FN_HIGH_BIT_MASK (OSSL_FN_ULONG_C(1) << (OSSL_FN_BYTES * 8 - 1))
 
 struct ossl_fn_st {
     /* Flag: alloced with OSSL_FN_new() or  OSSL_FN_secure_new() */
diff --git a/include/crypto/fn_intern.h b/include/crypto/fn_intern.h
new file mode 100644 (file)
index 0000000..df35a0a
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/**
+ * @file A set of internal functions to manipulate the OSSL_FN d array, and
+ * for introspection.
+ */
+
+#ifndef OPENSSL_FN_INTERN_H
+#define OPENSSL_FN_INTERN_H
+#pragma once
+
+#include <stdbool.h>
+#include "crypto/fn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if OSSL_FN_BYTES == 4
+/* 32-bit systems */
+#define OSSL_FN_ULONG_C(n) UINT32_C(n)
+#define OSSL_FN_ULONG64_C(hi32, lo32) OSSL_FN_ULONG_C(lo32), OSSL_FN_ULONG_C(hi32)
+#elif OSSL_FN_BYTES == 8
+/* 64-bit systems */
+#define OSSL_FN_ULONG_C(n) UINT64_C(n)
+#define OSSL_FN_ULONG64_C(hi32, lo32) (OSSL_FN_ULONG_C(hi32) << 32 | OSSL_FN_ULONG_C(lo32))
+#else
+#error "OpenSSL doesn't support large numbers on this platform"
+#endif
+
+int ossl_fn_set_words(OSSL_FN *f, const OSSL_FN_ULONG *words, size_t limbs);
+const OSSL_FN_ULONG *ossl_fn_get_words(OSSL_FN *f);
+
+size_t ossl_fn_get_dsize(OSSL_FN *f);
+
+void ossl_fn_set_negative(OSSL_FN *f, bool neg);
+
+bool ossl_fn_is_negative(OSSL_FN *f);
+bool ossl_fn_is_dynamically_allocated(OSSL_FN *f);
+bool ossl_fn_is_securely_allocated(OSSL_FN *f);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/crypto/fnerr.h b/include/crypto/fnerr.h
new file mode 100644 (file)
index 0000000..c3aeb32
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_CRYPTO_FNERR_H
+#define OSSL_CRYPTO_FNERR_H
+#pragma once
+
+#include <openssl/opensslconf.h>
+#include <openssl/symhacks.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ossl_err_load_OSSL_FN_strings(void);
+
+/*
+ * OSSL_FN reason codes.
+ */
+#define OSSL_FN_R_RESULT_ARG_TOO_SMALL 100
+
+#ifdef __cplusplus
+}
+#endif
+#endif
index d451f82eca655c11965eaf304b4469cac9c5e4c5..e1c076c2259dbdf1f3b8934b59f654dc69da111c 100644 (file)
@@ -124,6 +124,7 @@ struct err_state_st {
 #define ERR_LIB_OSSL_ENCODER 59
 #define ERR_LIB_OSSL_DECODER 60
 #define ERR_LIB_HTTP 61
+#define ERR_LIB_OSSL_FN 62
 
 #define ERR_LIB_USER 128
 
index fd3f17f03045579b4d5e296e74cd128836f4d6e5..b94422bee702c82392738a71af321dfbd4be9cbe 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "crypto/fn.h"
+#include "crypto/fn_intern.h"
 #include "fn_local.h"
 #include "testutil.h"
 
@@ -37,6 +38,7 @@ static int test_alloc(void)
 {
     int ret = 1;
     OSSL_FN *f = NULL;
+    const OSSL_FN_ULONG *u = NULL;
 
     /*
      * OSSL_FN_new_bits() calls OSSL_FN_new_bytes(), which calls
@@ -49,11 +51,12 @@ static int test_alloc(void)
      * shaving off 17 bits for demonstration purposes.
      */
     if (!TEST_ptr(f = OSSL_FN_new_bits(sizeof(OSSL_FN_ULONG) * 16 - 17))
-        || !TEST_uint_eq(f->is_dynamically_allocated, 1)
-        || !TEST_uint_eq(f->is_securely_allocated, 0)
-        || !TEST_int_eq(f->dsize, 2)
-        || !TEST_size_t_eq(f->d[0], 0)
-        || !TEST_size_t_eq(f->d[1], 0))
+        || !TEST_true(ossl_fn_is_dynamically_allocated(f))
+        || !TEST_false(ossl_fn_is_securely_allocated(f))
+        || !TEST_size_t_eq(ossl_fn_get_dsize(f), 2)
+        || !TEST_ptr(u = ossl_fn_get_words(f))
+        || !TEST_size_t_eq(u[0], 0)
+        || !TEST_size_t_eq(u[1], 0))
         ret = 0;
     OSSL_FN_free(f);
 
@@ -64,6 +67,7 @@ static int test_secure_alloc(void)
 {
     int ret = 1;
     OSSL_FN *f = NULL;
+    const OSSL_FN_ULONG *u = NULL;
 
     /*
      * OSSL_FN_secure_new_bits() calls OSSL_FN_secure_new_bytes(), which calls
@@ -76,11 +80,12 @@ static int test_secure_alloc(void)
      * shaving off 17 bits for demonstration purposes.
      */
     if (!TEST_ptr(f = OSSL_FN_secure_new_bits(sizeof(OSSL_FN_ULONG) * 16 - 17))
-        || !TEST_uint_eq(f->is_dynamically_allocated, 1)
-        || !TEST_uint_eq(f->is_securely_allocated, 1)
-        || !TEST_int_eq(f->dsize, 2)
-        || !TEST_size_t_eq(f->d[0], 0)
-        || !TEST_size_t_eq(f->d[1], 0))
+        || !TEST_true(ossl_fn_is_dynamically_allocated(f))
+        || !TEST_true(ossl_fn_is_securely_allocated(f))
+        || !TEST_size_t_eq(ossl_fn_get_dsize(f), 2)
+        || !TEST_ptr(u = ossl_fn_get_words(f))
+        || !TEST_size_t_eq(u[0], 0)
+        || !TEST_size_t_eq(u[1], 0))
         ret = 0;
     OSSL_FN_free(f);