2032 lines
83 KiB
Diff
2032 lines
83 KiB
Diff
commit 838ede224ad29ac3e1e6769bd00bf6be52185b5b
|
|
Author: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
Date: Mon Mar 30 10:19:40 2026 +0200
|
|
|
|
COMMON: Fix possible out-of-bounds access in BER decode functions
|
|
|
|
When decoding BER encoded data the length of the BER encoded data as well as
|
|
any length fields inside the BER encoded data must be validated to not cause
|
|
an out-of-bounds access to data behind the BER encoded data.
|
|
|
|
Add length parameters to any of the BER decoder functions to allow validation
|
|
of the decoded length information.
|
|
|
|
Reported-by: Sebastián Alba <sebasjosue84@gmail.com>
|
|
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
|
|
diff --git a/usr/lib/cca_stdll/cca_specific.c b/usr/lib/cca_stdll/cca_specific.c
|
|
index c6f08882..b99f99da 100644
|
|
--- a/usr/lib/cca_stdll/cca_specific.c
|
|
+++ b/usr/lib/cca_stdll/cca_specific.c
|
|
@@ -12404,8 +12404,8 @@ static CK_RV import_ec_pubkey(STDLL_TokData_t *tokdata, TEMPLATE *pub_templ)
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_OCTET_STRING(attr->pValue, &pubkey, &publen,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(attr->pValue, attr->ulValueLen,
|
|
+ &pubkey, &publen, &field_len);
|
|
if (rc != CKR_OK || attr->ulValueLen != field_len) {
|
|
TRACE_DEVEL("ber decoding of public key failed\n");
|
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
|
diff --git a/usr/lib/common/asn1.c b/usr/lib/common/asn1.c
|
|
index 93af67d3..c2e2d4b5 100644
|
|
--- a/usr/lib/common/asn1.c
|
|
+++ b/usr/lib/common/asn1.c
|
|
@@ -155,13 +155,13 @@ CK_ULONG ber_encode_INTEGER(CK_BBOOL length_only,
|
|
|
|
//
|
|
//
|
|
-CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
+CK_RV ber_decode_INTEGER(CK_BYTE *ber_int, CK_ULONG ber_int_len,
|
|
CK_BYTE **data, CK_ULONG *data_len,
|
|
CK_ULONG *field_len)
|
|
{
|
|
CK_ULONG len, length_octets;
|
|
|
|
- if (!ber_int) {
|
|
+ if (ber_int == NULL || ber_int_len < 2) {
|
|
TRACE_ERROR("Invalid function argument.\n");
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -181,9 +181,13 @@ CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
//
|
|
if ((ber_int[1] & 0x80) == 0) {
|
|
len = ber_int[1] & 0x7F;
|
|
+ if (1 + 1 + len > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &ber_int[2];
|
|
*data_len = len;
|
|
- if (ber_int[2] == 0x00) {
|
|
+ if (len > 0 && ber_int[2] == 0x00) {
|
|
*data = &ber_int[3];
|
|
*data_len = len - 1;
|
|
}
|
|
@@ -192,12 +196,20 @@ CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
}
|
|
|
|
length_octets = ber_int[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = ber_int[2];
|
|
+ if (1 + (1 + 1) + len > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &ber_int[3];
|
|
*data_len = len;
|
|
- if (ber_int[3] == 0x00) {
|
|
+ if (len > 0 && ber_int[3] == 0x00) {
|
|
*data = &ber_int[4];
|
|
*data_len = len - 1;
|
|
}
|
|
@@ -209,9 +221,13 @@ CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
len = ber_int[2];
|
|
len = len << 8;
|
|
len |= ber_int[3];
|
|
+ if (1 + (1 + 2) + len > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &ber_int[4];
|
|
*data_len = len;
|
|
- if (ber_int[4] == 0x00) {
|
|
+ if (len > 0 && ber_int[4] == 0x00) {
|
|
*data = &ber_int[5];
|
|
*data_len = len - 1;
|
|
}
|
|
@@ -225,9 +241,13 @@ CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
len |= ber_int[3];
|
|
len = len << 8;
|
|
len |= ber_int[4];
|
|
+ if (1 + (1 + 3) + len > ber_int_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &ber_int[5];
|
|
*data_len = len;
|
|
- if (ber_int[5] == 0x00) {
|
|
+ if (len > 0 && ber_int[5] == 0x00) {
|
|
*data = &ber_int[6];
|
|
*data_len = len - 1;
|
|
}
|
|
@@ -343,7 +363,7 @@ CK_RV ber_encode_OCTET_STRING(CK_BBOOL length_only,
|
|
|
|
//
|
|
//
|
|
-CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
+CK_RV ber_decode_OCTET_STRING(CK_BYTE *str, CK_ULONG str_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len)
|
|
{
|
|
@@ -352,7 +372,7 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
// I only support decoding primitive OCTET STRINGS
|
|
//
|
|
|
|
- if (!str) {
|
|
+ if (!str || str_len < 2) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -364,6 +384,10 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
//
|
|
if ((str[1] & 0x80) == 0) {
|
|
len = str[1] & 0x7F;
|
|
+ if (1 + 1 + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[2];
|
|
*data_len = len;
|
|
@@ -372,9 +396,17 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
}
|
|
|
|
length_octets = str[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = str[2];
|
|
+ if (1 + (1 + 1) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[3];
|
|
*data_len = len;
|
|
@@ -386,6 +418,10 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
len = str[2];
|
|
len = len << 8;
|
|
len |= str[3];
|
|
+ if (1 + (1 + 2) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[4];
|
|
*data_len = len;
|
|
@@ -399,6 +435,10 @@ CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
len |= str[3];
|
|
len = len << 8;
|
|
len |= str[4];
|
|
+ if (1 + (1 + 3) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[5];
|
|
*data_len = len;
|
|
@@ -515,13 +555,13 @@ CK_ULONG ber_encode_BIT_STRING(CK_BBOOL length_only,
|
|
* The first byte of output parm *data is the number of unused bits and must
|
|
* be removed later by the calling function.
|
|
*/
|
|
-CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
+CK_RV ber_decode_BIT_STRING(CK_BYTE *str, CK_ULONG str_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len)
|
|
{
|
|
CK_ULONG len, length_octets;
|
|
|
|
- if (!str) {
|
|
+ if (!str || str_len < 2) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -532,6 +572,15 @@ CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
|
|
if ((str[1] & 0x80) == 0) {
|
|
len = str[1] & 0x7F;
|
|
+ if (1 + 1 + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+ if (len < 1) {
|
|
+ TRACE_ERROR("BER length is too small to include the "
|
|
+ "unused-bits-byte\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[2];
|
|
*data_len = len;
|
|
@@ -540,9 +589,22 @@ CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
}
|
|
|
|
length_octets = str[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = str[2];
|
|
+ if (1 + (1 + 1) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+ if (len < 1) {
|
|
+ TRACE_ERROR("BER length is too small to include the "
|
|
+ "unused-bits-byte\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[3];
|
|
*data_len = len;
|
|
@@ -554,6 +616,15 @@ CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
len = str[2];
|
|
len = len << 8;
|
|
len |= str[3];
|
|
+ if (1 + (1 + 2) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+ if (len < 1) {
|
|
+ TRACE_ERROR("BER length is too small to include the "
|
|
+ "unused-bits-byte\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[4];
|
|
*data_len = len;
|
|
@@ -567,6 +638,15 @@ CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
len |= str[3];
|
|
len = len << 8;
|
|
len |= str[4];
|
|
+ if (1 + (1 + 3) + len > str_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+ if (len < 1) {
|
|
+ TRACE_ERROR("BER length is too small to include the "
|
|
+ "unused-bits-byte\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &str[5];
|
|
*data_len = len;
|
|
@@ -674,14 +754,14 @@ CK_RV ber_encode_SEQUENCE(CK_BBOOL length_only,
|
|
|
|
//
|
|
//
|
|
-CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
+CK_RV ber_decode_SEQUENCE(CK_BYTE *seq, CK_ULONG seq_len,
|
|
CK_BYTE **data, CK_ULONG *data_len,
|
|
CK_ULONG *field_len)
|
|
{
|
|
CK_ULONG len, length_octets;
|
|
|
|
|
|
- if (!seq) {
|
|
+ if (!seq || seq_len < 2) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -693,6 +773,10 @@ CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
//
|
|
if ((seq[1] & 0x80) == 0) {
|
|
len = seq[1] & 0x7F;
|
|
+ if (1 + 1 + len > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &seq[2];
|
|
*data_len = len;
|
|
@@ -701,9 +785,17 @@ CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
}
|
|
|
|
length_octets = seq[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = seq[2];
|
|
+ if (1 + (1 + 1) + len > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &seq[3];
|
|
*data_len = len;
|
|
@@ -715,6 +807,10 @@ CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
len = seq[2];
|
|
len = len << 8;
|
|
len |= seq[3];
|
|
+ if (1 + (1 + 2) + len > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &seq[4];
|
|
*data_len = len;
|
|
@@ -728,6 +824,10 @@ CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
len |= seq[3];
|
|
len = len << 8;
|
|
len |= seq[4];
|
|
+ if (1 + (1 + 3) + len > seq_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
*data = &seq[5];
|
|
*data_len = len;
|
|
@@ -834,7 +934,8 @@ CK_RV ber_encode_CHOICE(CK_BBOOL length_only,
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
-CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_BBOOL constructed,
|
|
+CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_ULONG choice_len,
|
|
+ CK_BBOOL constructed,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len,
|
|
CK_ULONG *option)
|
|
@@ -842,7 +943,7 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_BBOOL constructed,
|
|
CK_ULONG len, length_octets;
|
|
|
|
|
|
- if (!choice) {
|
|
+ if (!choice || choice_len < 2) {
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -858,6 +959,10 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_BBOOL constructed,
|
|
//
|
|
if ((choice[1] & 0x80) == 0) {
|
|
len = choice[1] & 0x7F;
|
|
+ if (1 + 1 + len > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &choice[2];
|
|
*data_len = len;
|
|
*field_len = 1 + (1) + len;
|
|
@@ -865,9 +970,17 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_BBOOL constructed,
|
|
}
|
|
|
|
length_octets = choice[1] & 0x7F;
|
|
+ if (1 + 1 + length_octets > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
|
|
if (length_octets == 1) {
|
|
len = choice[2];
|
|
+ if (1 + (1 + 1) + len > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &choice[3];
|
|
*data_len = len;
|
|
*field_len = 1 + (1 + 1) + len;
|
|
@@ -878,6 +991,10 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_BBOOL constructed,
|
|
len = choice[2];
|
|
len = len << 8;
|
|
len |= choice[3];
|
|
+ if (1 + (1 + 2) + len > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &choice[4];
|
|
*data_len = len;
|
|
*field_len = 1 + (1 + 2) + len;
|
|
@@ -890,6 +1007,10 @@ CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_BBOOL constructed,
|
|
len |= choice[3];
|
|
len = len << 8;
|
|
len |= choice[4];
|
|
+ if (1 + (1 + 3) + len > choice_len) {
|
|
+ TRACE_ERROR("BER length is larger than encoded data.\n");
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
*data = &choice[5];
|
|
*data_len = len;
|
|
*field_len = 1 + (1 + 3) + len;
|
|
@@ -1000,10 +1121,9 @@ error:
|
|
|
|
//
|
|
//
|
|
-CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
- CK_ULONG data_len,
|
|
- CK_BYTE **algorithm,
|
|
- CK_ULONG *alg_len, CK_BYTE **priv_key)
|
|
+CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data, CK_ULONG data_len,
|
|
+ CK_BYTE **algorithm, CK_ULONG *alg_len,
|
|
+ CK_BYTE **priv_key, CK_ULONG *priv_key_len)
|
|
{
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *alg = NULL;
|
|
@@ -1015,7 +1135,7 @@ CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
TRACE_ERROR("Invalid function arguments.\n");
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
- rc = ber_decode_SEQUENCE(data, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -1023,7 +1143,8 @@ CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
// version -- we just ignore this
|
|
//
|
|
offset = 0;
|
|
- rc = ber_decode_INTEGER(buf + offset, &ver, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &ver, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -1032,15 +1153,18 @@ CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
|
|
// 'buf' is now pointing to the PrivateKeyAlgorithmIdentifier
|
|
//
|
|
- rc = ber_decode_SEQUENCE(buf + offset, &alg, &len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(buf + offset, buf_len - offset, &alg, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
+ offset += field_len;
|
|
*algorithm = alg;
|
|
*alg_len = len;
|
|
|
|
- rc = ber_decode_OCTET_STRING(alg + len, priv_key, &buf_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(buf + offset, buf_len - offset,
|
|
+ priv_key, priv_key_len, &field_len);
|
|
if (rc != CKR_OK)
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
|
|
@@ -1058,13 +1182,14 @@ CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
* parameters ANY DEFINED BY algorithm OPTIONAL
|
|
* }
|
|
*/
|
|
-CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
+CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_ULONG spki_len,
|
|
+ CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
CK_BYTE **param, CK_ULONG *param_len,
|
|
CK_BYTE **key, CK_ULONG *key_len)
|
|
{
|
|
CK_BYTE *out_seq, *id_seq, *bit_str;
|
|
CK_BYTE *data;
|
|
- CK_ULONG data_len;
|
|
+ CK_ULONG data_len, out_seq_len, id_seq_len, bit_str_len;
|
|
CK_ULONG field_len;
|
|
CK_RV rc;
|
|
|
|
@@ -1072,7 +1197,9 @@ CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
*param_len = 0;
|
|
*key_len = 0;
|
|
out_seq = spki;
|
|
- rc = ber_decode_SEQUENCE(out_seq, &data, &data_len, &field_len);
|
|
+ out_seq_len = spki_len;
|
|
+ rc = ber_decode_SEQUENCE(out_seq, out_seq_len, &data, &data_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE #1 failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -1080,23 +1207,35 @@ CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
}
|
|
|
|
id_seq = out_seq + field_len - data_len;
|
|
+ id_seq_len = out_seq_len - field_len + data_len;
|
|
/* get id seq */
|
|
- rc = ber_decode_SEQUENCE(id_seq, &data, &data_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(id_seq, id_seq_len, &data, &data_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE #2 failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
return rc;
|
|
}
|
|
|
|
+ if (data_len < 2) {
|
|
+ TRACE_ERROR("%s Length of id_seq is too short\n", __func__);
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+
|
|
*alg_oid = data;
|
|
*alg_oid_len = data[1] + 2;
|
|
|
|
+ if (*alg_oid_len > data_len) {
|
|
+ TRACE_ERROR("%s Length of id_seq is too short\n", __func__);
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+ }
|
|
+
|
|
*param = data + *alg_oid_len;
|
|
*param_len = data_len - *alg_oid_len;
|
|
|
|
bit_str = id_seq + field_len;
|
|
+ bit_str_len = id_seq_len - field_len;
|
|
/* get bitstring */
|
|
- rc = ber_decode_BIT_STRING(bit_str, key, key_len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(bit_str, bit_str_len, key, key_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_BIT_STRING failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -1363,10 +1502,11 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *rsa_priv_key = NULL;
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG offset, buf_len, field_len, len;
|
|
+ CK_ULONG offset, buf_len, field_len, len, rsa_priv_key_len;
|
|
CK_RV rc;
|
|
|
|
- rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len, &rsa_priv_key);
|
|
+ rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len,
|
|
+ &rsa_priv_key, &rsa_priv_key_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -1378,7 +1518,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
- rc = ber_decode_SEQUENCE(rsa_priv_key, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(rsa_priv_key, rsa_priv_key_len,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK)
|
|
return rc;
|
|
|
|
@@ -1388,7 +1529,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// Version
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1397,7 +1539,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// modulus
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1406,7 +1549,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// public exponent
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1415,7 +1559,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// private exponent
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1424,7 +1569,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime #1
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1433,7 +1579,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime #2
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1442,7 +1589,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// exponent #1
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1451,7 +1599,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// exponent #2
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1460,7 +1609,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// coefficient
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1480,7 +1630,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// skip the version
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1489,7 +1640,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// modulus
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1504,7 +1656,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// public exponent
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1519,7 +1672,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// private exponent
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1534,7 +1688,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime #1
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1549,7 +1704,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime #2
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1564,7 +1720,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// exponent #1
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1579,7 +1736,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// exponent #2
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1594,7 +1752,8 @@ CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
|
|
|
|
// coefficient
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -1782,9 +1941,7 @@ CK_RV ber_decode_RSAPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, offset, len;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algid, &algid_len, ¶m, ¶m_len,
|
|
+ rc = ber_decode_SPKI(data, data_len, &algid, &algid_len, ¶m, ¶m_len,
|
|
&val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
@@ -1794,7 +1951,8 @@ CK_RV ber_decode_RSAPublicKey(CK_BYTE *data,
|
|
/*
|
|
* Make sure we're dealing with an DH key.
|
|
*/
|
|
- rc = ber_decode_SEQUENCE((CK_BYTE *)ber_AlgIdRSAEncryption, &algid_RSABase,
|
|
+ rc = ber_decode_SEQUENCE((CK_BYTE *)ber_AlgIdRSAEncryption,
|
|
+ ber_AlgIdRSAEncryptionLen, &algid_RSABase,
|
|
&len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
@@ -1806,20 +1964,21 @@ CK_RV ber_decode_RSAPublicKey(CK_BYTE *data,
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
- rc = ber_decode_SEQUENCE(val, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(val, val_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_INTEGER(seq, &mod, &mod_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq, seq_len, &mod, &mod_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
}
|
|
|
|
offset = field_len;
|
|
- rc = ber_decode_INTEGER(seq + offset, &exp, &exp_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq + offset, seq_len - offset, &exp, &exp_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -2053,11 +2212,12 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *dsakey = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG buf_len, field_len, len, offset;
|
|
+ CK_ULONG buf_len, field_len, len, dsakey_len, offset;
|
|
CK_RV rc;
|
|
|
|
|
|
- rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len, &dsakey);
|
|
+ rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len,
|
|
+ &dsakey, &dsakey_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -2071,7 +2231,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
}
|
|
// extract the parameter data into ATTRIBUTES
|
|
//
|
|
- rc = ber_decode_SEQUENCE(alg + ber_idDSALen, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(alg + ber_idDSALen, len- ber_idDSALen,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -2080,7 +2241,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2089,7 +2251,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// subprime
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2098,7 +2261,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// base
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2117,7 +2281,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// prime
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2132,7 +2297,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// subprime
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2147,7 +2313,8 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// base
|
|
//
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2162,7 +2329,7 @@ CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
|
|
|
|
// now get the private key
|
|
//
|
|
- rc = ber_decode_INTEGER(dsakey, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(dsakey, dsakey_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2405,9 +2572,7 @@ CK_RV ber_decode_DSAPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, offset;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algid, &algid_len, ¶m, ¶m_len,
|
|
+ rc = ber_decode_SPKI(data, data_len, &algid, &algid_len, ¶m, ¶m_len,
|
|
&val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
@@ -2422,27 +2587,29 @@ CK_RV ber_decode_DSAPublicKey(CK_BYTE *data,
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
- rc = ber_decode_SEQUENCE(param, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(param, param_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_INTEGER(seq, &p, &p_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq, seq_len, &p, &p_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
}
|
|
|
|
offset = field_len;
|
|
- rc = ber_decode_INTEGER(seq + offset, &sp, &sp_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq + offset, seq_len - offset, &sp, &sp_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
}
|
|
|
|
offset += field_len;
|
|
- rc = ber_decode_INTEGER(seq + offset, &b, &b_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq + offset, seq_len - offset, &b, &b_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -2541,8 +2708,8 @@ CK_RV der_encode_ECPrivateKey(CK_BBOOL length_only,
|
|
}
|
|
// public key bit string
|
|
if (pubkey && pubkey->pValue) {
|
|
- rc = ber_decode_OCTET_STRING(pubkey->pValue, &ecpoint, &ecpoint_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(pubkey->pValue, pubkey->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || pubkey->ulValueLen != field_len) {
|
|
TRACE_DEVEL("ber decoding of public key failed\n");
|
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
|
@@ -2624,8 +2791,8 @@ CK_RV der_encode_ECPrivateKey(CK_BBOOL length_only,
|
|
|
|
/* generate optional bit-string of public key */
|
|
if (pubkey && pubkey->pValue) {
|
|
- rc = ber_decode_OCTET_STRING(pubkey->pValue, &ecpoint, &ecpoint_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(pubkey->pValue, pubkey->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || pubkey->ulValueLen != field_len) {
|
|
TRACE_DEVEL("ber decoding of public key failed\n");
|
|
rc = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
@@ -2717,7 +2884,7 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *version = NULL;
|
|
CK_BYTE *choice = NULL;
|
|
CK_ULONG version_len, alg_len, priv_len, pub_len, parm_len, buf_len;
|
|
- CK_ULONG buf_offset, field_len, offset, choice_len, option;
|
|
+ CK_ULONG buf_offset, field_len, offset, choice_len, option, eckey_len;
|
|
CK_ULONG pubkey_available = 0;
|
|
CK_BYTE *ecpoint = NULL;
|
|
CK_ULONG ecpoint_len;
|
|
@@ -2731,7 +2898,7 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
* know the actual length to be able to find out of the optional public key
|
|
* is present or not.
|
|
*/
|
|
- rc = ber_decode_SEQUENCE(data, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -2743,7 +2910,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
data_len = field_len;
|
|
|
|
/* Decode PrivateKeyInfo into alg and eckey */
|
|
- rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &alg_len, &eckey);
|
|
+ rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &alg_len,
|
|
+ &eckey, &eckey_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -2756,7 +2924,7 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Decode the ecdhkey into buf */
|
|
- rc = ber_decode_SEQUENCE(eckey, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(eckey, eckey_len, &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -2764,7 +2932,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
/* Decode version (INTEGER) */
|
|
- rc = ber_decode_INTEGER(buf + offset, &version, &version_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &version, &version_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -2772,8 +2941,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
offset += field_len;
|
|
|
|
/* Decode private key (OCTET_STRING) */
|
|
- rc = ber_decode_OCTET_STRING(buf + offset, &priv_buf, &priv_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(buf + offset, buf_len - offset,
|
|
+ &priv_buf, &priv_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
goto cleanup;
|
|
@@ -2785,8 +2954,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
if (buf_offset + offset < data_len) {
|
|
|
|
/* Decode CHOICE */
|
|
- rc = ber_decode_CHOICE(buf + offset, TRUE, &choice, &choice_len,
|
|
- &field_len, &option);
|
|
+ rc = ber_decode_CHOICE(buf + offset, buf_len - offset, TRUE,
|
|
+ &choice, &choice_len, &field_len, &option);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_CHOICE failed\n");
|
|
goto cleanup;
|
|
@@ -2803,8 +2972,8 @@ CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
|
|
break;
|
|
case 1:
|
|
/* publicKey [1] BIT STRING OPTIONAL */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &pub_buf, &pub_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset,
|
|
+ &pub_buf, &pub_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING failed\n");
|
|
goto cleanup;
|
|
@@ -2887,7 +3056,8 @@ CK_RV ber_encode_ECPublicKey(CK_BBOOL length_only, CK_BYTE **data,
|
|
CK_ULONG ecpoint_len, field_len;
|
|
|
|
/* CKA_EC_POINT is an BER encoded OCTET STRING. Extract it. */
|
|
- rc = ber_decode_OCTET_STRING((CK_BYTE *)point->pValue, &ecpoint,
|
|
+ rc = ber_decode_OCTET_STRING((CK_BYTE *)point->pValue,
|
|
+ point->ulValueLen, &ecpoint,
|
|
&ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || point->ulValueLen != field_len) {
|
|
TRACE_DEVEL("%s ber_decode_OCTET_STRING failed\n", __func__);
|
|
@@ -3018,9 +3188,7 @@ CK_RV der_decode_ECPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, len;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algid, &algid_len, ¶m, ¶m_len,
|
|
+ rc = ber_decode_SPKI(data, data_len, &algid, &algid_len, ¶m, ¶m_len,
|
|
&point, &point_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
@@ -3032,8 +3200,9 @@ CK_RV der_decode_ECPublicKey(CK_BYTE *data,
|
|
* Extract base alg-id of DER encoded EC byte string
|
|
* and compare against the decoded alg-id from the inner sequence
|
|
*/
|
|
- rc = ber_decode_SEQUENCE((CK_BYTE *)der_AlgIdECBase, &algid_ECBase, &len,
|
|
- &field_len);
|
|
+ rc = ber_decode_SEQUENCE((CK_BYTE *)der_AlgIdECBase,
|
|
+ der_AlgIdECBaseLen, &algid_ECBase,
|
|
+ &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -3251,10 +3420,11 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *dhkey = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG buf_len, field_len, len, offset;
|
|
+ CK_ULONG buf_len, field_len, len, dhkey_len, offset;
|
|
CK_RV rc;
|
|
|
|
- rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len, &dhkey);
|
|
+ rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len,
|
|
+ &dhkey, &dhkey_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -3267,7 +3437,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
}
|
|
// extract the parameter data into ATTRIBUTES
|
|
//
|
|
- rc = ber_decode_SEQUENCE(alg + ber_idDHLen, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(alg + ber_idDHLen, len - ber_idDHLen,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
@@ -3275,7 +3446,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
// prime
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3283,7 +3455,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
offset += field_len;
|
|
|
|
// base
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3299,7 +3472,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
// prime
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3313,7 +3487,8 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
// base
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset,
|
|
+ &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3327,7 +3502,7 @@ CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
// now get the private key
|
|
- rc = ber_decode_INTEGER(dhkey, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(dhkey, dhkey_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -3549,9 +3724,7 @@ CK_RV ber_decode_DHPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, offset;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algid, &algid_len, ¶m, ¶m_len,
|
|
+ rc = ber_decode_SPKI(data, data_len, &algid, &algid_len, ¶m, ¶m_len,
|
|
&val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
@@ -3566,20 +3739,21 @@ CK_RV ber_decode_DHPublicKey(CK_BYTE *data,
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
- rc = ber_decode_SEQUENCE(param, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(param, param_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_INTEGER(seq, &p, &p_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq, seq_len, &p, &p_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
}
|
|
|
|
offset = field_len;
|
|
- rc = ber_decode_INTEGER(seq + offset, &b, &b_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(seq + offset, seq_len - offset, &b, &b_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -3823,10 +3997,8 @@ static CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, offset, raw_spki_len;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algoid, &algoid_len, ¶m, ¶m_len,
|
|
- &val, &val_len);
|
|
+ rc = ber_decode_SPKI(data, data_len, &algoid, &algoid_len,
|
|
+ ¶m, ¶m_len, &val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
return rc;
|
|
@@ -3843,14 +4015,14 @@ static CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
|
|
* BIT STRING = rho
|
|
* BIT STRING = t1
|
|
*/
|
|
- rc = ber_decode_SEQUENCE(val, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(val, val_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
/* Decode rho */
|
|
- rc = ber_decode_BIT_STRING(seq, &rho, &rho_len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(seq, seq_len, &rho, &rho_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -3860,7 +4032,8 @@ static CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
|
|
|
|
/* Decode t1 */
|
|
offset = field_len;
|
|
- rc = ber_decode_BIT_STRING(seq + offset, &t1, &t1_len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(seq + offset, seq_len - offset, &t1, &t1_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -3883,7 +4056,7 @@ static CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Add raw SPKI as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &val, &val_len, &raw_spki_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &val, &val_len, &raw_spki_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
|
|
goto cleanup;
|
|
@@ -4179,12 +4352,13 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *dilithium_priv_key = NULL;
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG offset, buf_len, field_len, len, option;
|
|
+ CK_ULONG offset, buf_len, field_len, len, dilithium_priv_key_len, option;
|
|
CK_RV rc;
|
|
|
|
/* Check if this is a Dilithium private key */
|
|
rc = ber_decode_PrivateKeyInfo(data, data_len, &algoid, &len,
|
|
- &dilithium_priv_key);
|
|
+ &dilithium_priv_key,
|
|
+ &dilithium_priv_key_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -4203,7 +4377,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Decode private Dilithium key */
|
|
- rc = ber_decode_SEQUENCE(dilithium_priv_key, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(dilithium_priv_key, dilithium_priv_key_len,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK)
|
|
return rc;
|
|
|
|
@@ -4211,7 +4386,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
/* Skip the version */
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -4219,7 +4395,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
offset += field_len;
|
|
|
|
/* rho */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (rho) failed\n");
|
|
goto cleanup;
|
|
@@ -4235,7 +4412,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* seed */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (seed) failed\n");
|
|
goto cleanup;
|
|
@@ -4251,7 +4429,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* tr */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (tr) failed\n");
|
|
goto cleanup;
|
|
@@ -4267,7 +4446,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* s1 */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (s1) failed\n");
|
|
goto cleanup;
|
|
@@ -4283,7 +4463,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* s2 */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (s2) failed\n");
|
|
goto cleanup;
|
|
@@ -4299,7 +4480,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* t0 */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (t0) failed\n");
|
|
goto cleanup;
|
|
@@ -4316,8 +4498,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
|
|
/* t1 (optional, within choice) */
|
|
if (offset < buf_len) {
|
|
- rc = ber_decode_CHOICE(buf + offset, TRUE, &tmp, &len, &field_len,
|
|
- &option);
|
|
+ rc = ber_decode_CHOICE(buf + offset, buf_len - offset, TRUE,
|
|
+ &tmp, &len, &field_len, &option);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (t1) failed\n");
|
|
goto cleanup;
|
|
@@ -4331,7 +4513,8 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
|
|
offset += field_len - len;
|
|
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (t1) failed\n");
|
|
goto cleanup;
|
|
@@ -4355,7 +4538,7 @@ static CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Add private key as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
|
|
goto cleanup;
|
|
@@ -4577,10 +4760,8 @@ static CK_RV ber_decode_IBM_KyberPublicKey(CK_BYTE *data,
|
|
CK_ULONG field_len, raw_spki_len;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(data_len); // XXX can this parameter be removed ?
|
|
-
|
|
- rc = ber_decode_SPKI(data, &algoid, &algoid_len, ¶m, ¶m_len,
|
|
- &val, &val_len);
|
|
+ rc = ber_decode_SPKI(data, data_len, &algoid, &algoid_len,
|
|
+ ¶m, ¶m_len, &val, &val_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
return rc;
|
|
@@ -4596,14 +4777,14 @@ static CK_RV ber_decode_IBM_KyberPublicKey(CK_BYTE *data,
|
|
* SEQUENCE (1 elem)
|
|
* BIT STRING = pk
|
|
*/
|
|
- rc = ber_decode_SEQUENCE(val, &seq, &seq_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(val, val_len, &seq, &seq_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
/* Decode pk */
|
|
- rc = ber_decode_BIT_STRING(seq, &pk, &pk_len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(seq, seq_len, &pk, &pk_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
return rc;
|
|
@@ -4619,7 +4800,7 @@ static CK_RV ber_decode_IBM_KyberPublicKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Add raw SPKI as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &val, &val_len, &raw_spki_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &val, &val_len, &raw_spki_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
|
|
goto cleanup;
|
|
@@ -4845,12 +5026,12 @@ static CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
CK_BYTE *kyber_priv_key = NULL;
|
|
CK_BYTE *buf = NULL;
|
|
CK_BYTE *tmp = NULL;
|
|
- CK_ULONG offset, buf_len, field_len, len, option;
|
|
+ CK_ULONG offset, buf_len, field_len, len, kyber_priv_key_len, option;
|
|
CK_RV rc;
|
|
|
|
/* Check if this is a Kyber private key */
|
|
rc = ber_decode_PrivateKeyInfo(data, data_len, &algoid, &len,
|
|
- &kyber_priv_key);
|
|
+ &kyber_priv_key, &kyber_priv_key_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -4869,7 +5050,8 @@ static CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Decode private Kyber key */
|
|
- rc = ber_decode_SEQUENCE(kyber_priv_key, &buf, &buf_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(kyber_priv_key, kyber_priv_key_len,
|
|
+ &buf, &buf_len, &field_len);
|
|
if (rc != CKR_OK)
|
|
return rc;
|
|
|
|
@@ -4877,7 +5059,8 @@ static CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
offset = 0;
|
|
|
|
/* Skip the version */
|
|
- rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_INTEGER(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_INTEGER failed\n");
|
|
goto cleanup;
|
|
@@ -4885,7 +5068,8 @@ static CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
offset += field_len;
|
|
|
|
/* sk */
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (sk) failed\n");
|
|
goto cleanup;
|
|
@@ -4902,8 +5086,8 @@ static CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
|
|
/* pk (optional, within choice) */
|
|
if (offset < buf_len) {
|
|
- rc = ber_decode_CHOICE(buf + offset, TRUE, &tmp, &len, &field_len,
|
|
- &option);
|
|
+ rc = ber_decode_CHOICE(buf + offset, buf_len - offset, TRUE,
|
|
+ &tmp, &len, &field_len, &option);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (t1) failed\n");
|
|
goto cleanup;
|
|
@@ -4917,7 +5101,8 @@ static CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
|
|
offset += field_len - len;
|
|
|
|
- rc = ber_decode_BIT_STRING(buf + offset, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_BIT_STRING(buf + offset, buf_len - offset, &tmp, &len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_BIT_STRING of (pk) failed\n");
|
|
goto cleanup;
|
|
@@ -4944,7 +5129,7 @@ static CK_RV ber_decode_IBM_KyberPrivateKey(CK_BYTE *data,
|
|
}
|
|
|
|
/* Add private key as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
|
|
goto cleanup;
|
|
@@ -5102,8 +5287,8 @@ CK_RV ber_decode_IBM_ML_DSA_PublicKey(CK_MECHANISM_TYPE mech,
|
|
* BIT STRING - public key (rho | t1)
|
|
*/
|
|
|
|
- rc = ber_decode_SPKI(data, &algoid, &algoid_len, ¶m, ¶m_len,
|
|
- &pub, &pub_len);
|
|
+ rc = ber_decode_SPKI(data, data_len, &algoid, &algoid_len,
|
|
+ ¶m, ¶m_len, &pub, &pub_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
return rc;
|
|
@@ -5139,7 +5324,7 @@ CK_RV ber_decode_IBM_ML_DSA_PublicKey(CK_MECHANISM_TYPE mech,
|
|
}
|
|
|
|
/* Add raw SPKI as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &pub, &pub_len, &raw_spki_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &pub, &pub_len, &raw_spki_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -5375,7 +5560,7 @@ CK_RV ber_decode_IBM_ML_DSA_PrivateKey(CK_MECHANISM_TYPE mech,
|
|
CK_BYTE *algid = NULL, *priv = NULL, *both = NULL, *key = NULL;
|
|
CK_BYTE *pseed = NULL, *tmp = NULL;
|
|
CK_ULONG both_len, field_len, algid_len, key_len = 0, pseed_len = 0;
|
|
- CK_ULONG ofs = 0, option, len;
|
|
+ CK_ULONG ofs = 0, option, len, priv_len;
|
|
CK_RV rc;
|
|
|
|
if (mech == CKM_IBM_DILITHIUM) {
|
|
@@ -5387,7 +5572,7 @@ CK_RV ber_decode_IBM_ML_DSA_PrivateKey(CK_MECHANISM_TYPE mech,
|
|
|
|
/* Check if this is a ML-DSA private key */
|
|
rc = ber_decode_PrivateKeyInfo(data, data_len, &algid, &algid_len,
|
|
- &priv);
|
|
+ &priv, &priv_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -5413,35 +5598,37 @@ CK_RV ber_decode_IBM_ML_DSA_PrivateKey(CK_MECHANISM_TYPE mech,
|
|
*/
|
|
switch (priv[0]) {
|
|
case 0x30: /* SEQUENCE - both format*/
|
|
- rc = ber_decode_SEQUENCE(priv, &both, &both_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(priv, priv_len, &both, &both_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_OCTET_STRING(both, &pseed, &pseed_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(both, both_len, &pseed, &pseed_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_OCTET_STRING(both + field_len, &key, &key_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(both + field_len, both_len - field_len,
|
|
+ &key, &key_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
return rc;
|
|
}
|
|
break;
|
|
case 0x04: /* OCTET STRING - expanded key */
|
|
- rc = ber_decode_OCTET_STRING(priv, &key, &key_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(priv, priv_len, &key, &key_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
return rc;
|
|
}
|
|
break;
|
|
case 0x80: /* CHOICE - private seed only */
|
|
- rc = ber_decode_CHOICE(priv, FALSE, &pseed, &pseed_len, &field_len,
|
|
- &option);
|
|
+ rc = ber_decode_CHOICE(priv, priv_len, FALSE, &pseed, &pseed_len,
|
|
+ &field_len, &option);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_CHOICE failed\n");
|
|
return rc;
|
|
@@ -5529,7 +5716,7 @@ CK_RV ber_decode_IBM_ML_DSA_PrivateKey(CK_MECHANISM_TYPE mech,
|
|
}
|
|
|
|
/* Add private key as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -5689,8 +5876,8 @@ CK_RV ber_decode_IBM_ML_KEM_PublicKey(CK_MECHANISM_TYPE mech,
|
|
* BIT STRING - public key (pk)
|
|
*/
|
|
|
|
- rc = ber_decode_SPKI(data, &algoid, &algoid_len, ¶m, ¶m_len,
|
|
- &pub, &pub_len);
|
|
+ rc = ber_decode_SPKI(data, data_len, &algoid, &algoid_len,
|
|
+ ¶m, ¶m_len, &pub, &pub_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
return rc;
|
|
@@ -5716,7 +5903,7 @@ CK_RV ber_decode_IBM_ML_KEM_PublicKey(CK_MECHANISM_TYPE mech,
|
|
}
|
|
|
|
/* Add raw SPKI as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &pub, &pub_len, &raw_spki_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &pub, &pub_len, &raw_spki_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -5898,7 +6085,7 @@ CK_RV ber_decode_IBM_ML_KEM_PrivateKey(CK_MECHANISM_TYPE mech,
|
|
CK_BYTE *algid = NULL, *priv = NULL, *both = NULL, *key = NULL;
|
|
CK_BYTE *pseed = NULL, *tmp = NULL;
|
|
CK_ULONG both_len, field_len, algid_len, key_len = 0, pseed_len = 0;
|
|
- CK_ULONG option, len;
|
|
+ CK_ULONG option, len, priv_len;
|
|
CK_RV rc;
|
|
|
|
if (mech == CKM_IBM_KYBER) {
|
|
@@ -5909,7 +6096,7 @@ CK_RV ber_decode_IBM_ML_KEM_PrivateKey(CK_MECHANISM_TYPE mech,
|
|
|
|
/* Check if this is a ML-KEM private key */
|
|
rc = ber_decode_PrivateKeyInfo(data, data_len, &algid, &algid_len,
|
|
- &priv);
|
|
+ &priv, &priv_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
|
|
return rc;
|
|
@@ -5935,35 +6122,37 @@ CK_RV ber_decode_IBM_ML_KEM_PrivateKey(CK_MECHANISM_TYPE mech,
|
|
*/
|
|
switch (priv[0]) {
|
|
case 0x30: /* SEQUENCE - both format*/
|
|
- rc = ber_decode_SEQUENCE(priv, &both, &both_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(priv, priv_len, &both, &both_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_OCTET_STRING(both, &pseed, &pseed_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(both, both_len, &pseed, &pseed_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
return rc;
|
|
}
|
|
|
|
- rc = ber_decode_OCTET_STRING(both + field_len, &key, &key_len,
|
|
- &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(both + field_len, both_len - field_len,
|
|
+ &key, &key_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
return rc;
|
|
}
|
|
break;
|
|
case 0x04: /* OCTET STRING - expanded key */
|
|
- rc = ber_decode_OCTET_STRING(priv, &key, &key_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(priv, priv_len, &key, &key_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
return rc;
|
|
}
|
|
break;
|
|
case 0x80: /* CHOICE - private seed only */
|
|
- rc = ber_decode_CHOICE(priv, FALSE, &pseed, &pseed_len, &field_len,
|
|
- &option);
|
|
+ rc = ber_decode_CHOICE(priv, priv_len, FALSE, &pseed, &pseed_len,
|
|
+ &field_len, &option);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_CHOICE failed\n");
|
|
return rc;
|
|
@@ -6006,7 +6195,7 @@ CK_RV ber_decode_IBM_ML_KEM_PrivateKey(CK_MECHANISM_TYPE mech,
|
|
}
|
|
|
|
/* Add private key as CKA_VALUE to public key (z/OS ICSF compatibility) */
|
|
- rc = ber_decode_SEQUENCE(data, &tmp, &len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(data, data_len, &tmp, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h
|
|
index 884bc9ed..c61969b6 100644
|
|
--- a/usr/lib/common/h_extern.h
|
|
+++ b/usr/lib/common/h_extern.h
|
|
@@ -2923,7 +2923,7 @@ CK_ULONG ber_encode_INTEGER(CK_BBOOL length_only,
|
|
CK_ULONG *ber_int_len,
|
|
CK_BYTE *data, CK_ULONG data_len);
|
|
|
|
-CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
|
|
+CK_RV ber_decode_INTEGER(CK_BYTE *ber_int, CK_ULONG ber_int_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len);
|
|
|
|
@@ -2933,7 +2933,7 @@ CK_ULONG ber_encode_BIT_STRING(CK_BBOOL length_only,
|
|
CK_ULONG data_len,
|
|
CK_BYTE unused_bits);
|
|
|
|
-CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
|
|
+CK_RV ber_decode_BIT_STRING(CK_BYTE *str, CK_ULONG str_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len);
|
|
|
|
@@ -2942,7 +2942,7 @@ CK_RV ber_encode_OCTET_STRING(CK_BBOOL length_only,
|
|
CK_ULONG *str_len,
|
|
CK_BYTE *data, CK_ULONG data_len);
|
|
|
|
-CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
|
|
+CK_RV ber_decode_OCTET_STRING(CK_BYTE *str, CK_ULONG str_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len);
|
|
|
|
@@ -2951,7 +2951,7 @@ CK_RV ber_encode_SEQUENCE(CK_BBOOL length_only,
|
|
CK_ULONG *seq_len,
|
|
CK_BYTE *data, CK_ULONG data_len);
|
|
|
|
-CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
|
|
+CK_RV ber_decode_SEQUENCE(CK_BYTE *seq, CK_ULONG seq_len,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len);
|
|
|
|
@@ -2961,7 +2961,8 @@ CK_RV ber_encode_CHOICE(CK_BBOOL length_only,
|
|
CK_ULONG *str_len, CK_BYTE *data, CK_ULONG data_len,
|
|
CK_BBOOL constructed);
|
|
|
|
-CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_BBOOL constructed,
|
|
+CK_RV ber_decode_CHOICE(CK_BYTE *choice, CK_ULONG choice_len,
|
|
+ CK_BBOOL constructed,
|
|
CK_BYTE **data,
|
|
CK_ULONG *data_len, CK_ULONG *field_len,
|
|
CK_ULONG *option);
|
|
@@ -2973,12 +2974,12 @@ CK_RV ber_encode_PrivateKeyInfo(CK_BBOOL length_only,
|
|
const CK_ULONG algorithm_id_len,
|
|
CK_BYTE *priv_key, CK_ULONG priv_key_len);
|
|
|
|
-CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
|
|
- CK_ULONG data_len,
|
|
- CK_BYTE **algorithm_id,
|
|
- CK_ULONG *alg_len, CK_BYTE **priv_key);
|
|
+CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data, CK_ULONG data_len,
|
|
+ CK_BYTE **algorithm_id, CK_ULONG *alg_len,
|
|
+ CK_BYTE **priv_key, CK_ULONG *priv_key_len);
|
|
|
|
-CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
+CK_RV ber_decode_SPKI(CK_BYTE *spki, CK_ULONG spki_len,
|
|
+ CK_BYTE **alg_oid, CK_ULONG *alg_oid_len,
|
|
CK_BYTE **param, CK_ULONG *param_len,
|
|
CK_BYTE **key, CK_ULONG *key_len);
|
|
|
|
diff --git a/usr/lib/common/key_mgr.c b/usr/lib/common/key_mgr.c
|
|
index 08b38a80..4d100307 100644
|
|
--- a/usr/lib/common/key_mgr.c
|
|
+++ b/usr/lib/common/key_mgr.c
|
|
@@ -1656,10 +1656,11 @@ CK_RV key_mgr_get_private_key_type(CK_BYTE *keydata,
|
|
{
|
|
CK_BYTE *alg = NULL;
|
|
CK_BYTE *priv_key = NULL;
|
|
- CK_ULONG alg_len, i;
|
|
+ CK_ULONG alg_len, priv_key_len, i;
|
|
CK_RV rc;
|
|
|
|
- rc = ber_decode_PrivateKeyInfo(keydata, keylen, &alg, &alg_len, &priv_key);
|
|
+ rc = ber_decode_PrivateKeyInfo(keydata, keylen, &alg, &alg_len,
|
|
+ &priv_key, &priv_key_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed.\n");
|
|
return rc;
|
|
diff --git a/usr/lib/common/mech_ec.c b/usr/lib/common/mech_ec.c
|
|
index ce031ec0..2b1609e4 100644
|
|
--- a/usr/lib/common/mech_ec.c
|
|
+++ b/usr/lib/common/mech_ec.c
|
|
@@ -1511,7 +1511,7 @@ int ec_point_from_public_data(const CK_BYTE *data, CK_ULONG data_len,
|
|
|
|
check_encoded:
|
|
/* If we reach here, try to BER decode it as OCTET-STRING */
|
|
- rc = ber_decode_OCTET_STRING((CK_BYTE *)data, &value, &value_len,
|
|
+ rc = ber_decode_OCTET_STRING((CK_BYTE *)data, data_len, &value, &value_len,
|
|
&field_len);
|
|
if (rc == CKR_OK && field_len == data_len && value_len <= data_len - 2) {
|
|
/* Looks like a BER encoded EC Point */
|
|
@@ -1776,6 +1776,7 @@ CK_RV ecdh_aes_key_wrap(STDLL_TokData_t *tokdata, SESSION *sess,
|
|
}
|
|
|
|
rc = ber_decode_OCTET_STRING((CK_BYTE *)ec_point->pValue,
|
|
+ ec_point->ulValueLen,
|
|
&pub_ec_point, &pub_ec_point_len, &field_len);
|
|
if (rc != CKR_OK || field_len != ec_point->ulValueLen) {
|
|
rc = CKR_FUNCTION_FAILED;
|
|
@@ -1796,6 +1797,7 @@ CK_RV ecdh_aes_key_wrap(STDLL_TokData_t *tokdata, SESSION *sess,
|
|
}
|
|
|
|
rc = ber_decode_OCTET_STRING((CK_BYTE *)ec_point->pValue,
|
|
+ ec_point->ulValueLen,
|
|
&ecdh_params.pPublicData,
|
|
&ecdh_params.ulPublicDataLen,
|
|
&field_len);
|
|
diff --git a/usr/lib/common/pkey_utils.c b/usr/lib/common/pkey_utils.c
|
|
index 0a9f77e7..241629f8 100644
|
|
--- a/usr/lib/common/pkey_utils.c
|
|
+++ b/usr/lib/common/pkey_utils.c
|
|
@@ -1604,8 +1604,8 @@ struct { \
|
|
}
|
|
|
|
/* CKA_EC_POINT is an BER encoded OCTET STRING. Extract it. */
|
|
- rc = ber_decode_OCTET_STRING(pub_attr->pValue, &ecpoint,
|
|
- &ecpoint_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(pub_attr->pValue, pub_attr->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || pub_attr->ulValueLen != field_len) {
|
|
TRACE_ERROR("%s: ber_decode_OCTET_STRING failed\n", __func__);
|
|
ret = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
@@ -1752,8 +1752,8 @@ struct { \
|
|
}
|
|
|
|
/* CKA_EC_POINT is an BER encoded OCTET STRING. Extract it. */
|
|
- rc = ber_decode_OCTET_STRING(pub_attr->pValue, &ecpoint,
|
|
- &ecpoint_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(pub_attr->pValue, pub_attr->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || pub_attr->ulValueLen != field_len) {
|
|
TRACE_ERROR("%s: ber_decode_OCTET_STRING failed\n", __func__);
|
|
ret = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
diff --git a/usr/lib/ep11_stdll/ep11_login.c b/usr/lib/ep11_stdll/ep11_login.c
|
|
index 10f1366e..e89e1b5c 100644
|
|
--- a/usr/lib/ep11_stdll/ep11_login.c
|
|
+++ b/usr/lib/ep11_stdll/ep11_login.c
|
|
@@ -113,13 +113,14 @@ static CK_RV get_login_importer_key(target_t target,
|
|
* tcounter OCTET STRING (16 bytes)
|
|
*/
|
|
|
|
- rc = ber_decode_SEQUENCE(res, &data, &data_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(res, reslen, &data, &data_len, &field_len);
|
|
if (rc != CKR_OK || field_len > reslen) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed\n", __func__);
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
- rc = ber_decode_OCTET_STRING(data, &ski_field, &ski_field_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(data, data_len, &ski_field, &ski_field_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK || field_len > data_len) {
|
|
TRACE_ERROR("%s ber_decode_OCTET_STRING (SKI) failed\n", __func__);
|
|
return CKR_FUNCTION_FAILED;
|
|
@@ -128,7 +129,7 @@ static CK_RV get_login_importer_key(target_t target,
|
|
data += field_len;
|
|
data_len -= field_len;
|
|
|
|
- rc = ber_decode_OCTET_STRING(data, &spki, &spki_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(data, data_len, &spki, &spki_len, &field_len);
|
|
if (rc != CKR_OK || field_len > data_len) {
|
|
TRACE_ERROR("%s ber_decode_OCTET_STRING (SPKI) failed\n", __func__);
|
|
return CKR_FUNCTION_FAILED;
|
|
@@ -137,7 +138,7 @@ static CK_RV get_login_importer_key(target_t target,
|
|
data += field_len;
|
|
data_len -= field_len;
|
|
|
|
- rc = ber_decode_OCTET_STRING(data, &cnt, &cnt_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(data, data_len, &cnt, &cnt_len, &field_len);
|
|
if (rc != CKR_OK || field_len > data_len) {
|
|
TRACE_ERROR("%s ber_decode_OCTET_STRING (COUNTER) failed\n", __func__);
|
|
return CKR_FUNCTION_FAILED;
|
|
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
|
|
index cb474ebe..df41be57 100644
|
|
--- a/usr/lib/ep11_stdll/ep11_specific.c
|
|
+++ b/usr/lib/ep11_stdll/ep11_specific.c
|
|
@@ -1586,7 +1586,8 @@ CK_RV ep11tok_extract_blob_info(CK_BYTE *blob, CK_ULONG blob_len,
|
|
* denoted by 0x30 followed by the DER encoded length of the SPKI.
|
|
*/
|
|
if (blob_len > 5 && blob[0] == 0x30 &&
|
|
- ber_decode_SEQUENCE(blob, &data, &data_len, &field_len) == CKR_OK) {
|
|
+ ber_decode_SEQUENCE(blob, blob_len, &data, &data_len,
|
|
+ &field_len) == CKR_OK) {
|
|
/* It is a SPKI, fields follow as OCTET STRINGs right after SPKI data */
|
|
if (blob_len < field_len) {
|
|
TRACE_ERROR("MACed SPKI is too small\n");
|
|
@@ -1617,7 +1618,8 @@ CK_RV ep11tok_extract_blob_info(CK_BYTE *blob, CK_ULONG blob_len,
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
|
|
- if (ber_decode_OCTET_STRING(blob + ofs, &data, &data_len,
|
|
+ if (ber_decode_OCTET_STRING(blob + ofs, blob_len - ofs,
|
|
+ &data, &data_len,
|
|
&field_len) != CKR_OK) {
|
|
TRACE_ERROR("Failed to decode MACed SPKI field %s\n",
|
|
fields[i].field);
|
|
@@ -3671,7 +3673,8 @@ static CK_RV make_maced_spki(STDLL_TokData_t *tokdata, SESSION *sess,
|
|
CK_RV rc;
|
|
|
|
if (spki_len < 6 ||
|
|
- ber_decode_SEQUENCE(spki, &tmp, &tmp_len, &seq_len) != CKR_OK) {
|
|
+ ber_decode_SEQUENCE(spki, spki_len, &tmp, &tmp_len,
|
|
+ &seq_len) != CKR_OK) {
|
|
TRACE_ERROR("%s Its not an SPKI\n", __func__);
|
|
return CKR_FUNCTION_FAILED;
|
|
}
|
|
@@ -3798,9 +3801,7 @@ static int get_curve_type_from_spki(CK_BYTE *spki, CK_ULONG spki_len)
|
|
CK_ULONG field_len, len, i;
|
|
CK_RV rc;
|
|
|
|
- UNUSED(spki_len);
|
|
-
|
|
- rc = ber_decode_SPKI(spki, &algid, &algid_len, ¶m, ¶m_len,
|
|
+ rc = ber_decode_SPKI(spki, spki_len, &algid, &algid_len, ¶m, ¶m_len,
|
|
&pubkey, &pubkey_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SPKI failed\n");
|
|
@@ -3812,8 +3813,8 @@ static int get_curve_type_from_spki(CK_BYTE *spki, CK_ULONG spki_len)
|
|
* Extract base alg-id of DER encoded EC byte string
|
|
* and compare against the decoded alg-id from the inner sequence
|
|
*/
|
|
- rc = ber_decode_SEQUENCE((CK_BYTE *)der_AlgIdECBase, &algid_ECBase, &len,
|
|
- &field_len);
|
|
+ rc = ber_decode_SEQUENCE((CK_BYTE *)der_AlgIdECBase, der_AlgIdECBaseLen,
|
|
+ &algid_ECBase, &len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
|
|
return -1;
|
|
@@ -4335,8 +4336,9 @@ static CK_RV import_EC_key(STDLL_TokData_t *tokdata, SESSION *sess,
|
|
}
|
|
|
|
/* CKA_EC_POINT is an BER encoded OCTET STRING. Extract it. */
|
|
- rc = ber_decode_OCTET_STRING((CK_BYTE *)ec_point_attr->pValue, &ecpoint,
|
|
- &ecpoint_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING((CK_BYTE *)ec_point_attr->pValue,
|
|
+ ec_point_attr->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (rc != CKR_OK || ec_point_attr->ulValueLen != field_len) {
|
|
TRACE_DEVEL("%s ber_decode_OCTET_STRING failed\n", __func__);
|
|
rc = CKR_ATTRIBUTE_VALUE_INVALID;
|
|
@@ -5295,7 +5297,7 @@ static CK_RV import_blob_private_public(STDLL_TokData_t *tokdata, SESSION *sess,
|
|
}
|
|
|
|
/* SPKI is a MACed SPKI, get length of SPKI part only */
|
|
- rc = ber_decode_SEQUENCE(spki, &data, &data_len, &raw_spki_len);
|
|
+ rc = ber_decode_SEQUENCE(spki, spki_len, &data, &data_len, &raw_spki_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -6189,7 +6191,7 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
|
|
|
|
if (spkisize > 0 && (class == CKO_PRIVATE_KEY || class == CKO_PUBLIC_KEY)) {
|
|
/* spki may be a MACed SPKI, get length of SPKI part only */
|
|
- rc = ber_decode_SEQUENCE(spki, &temp, &temp_len, &spkisize);
|
|
+ rc = ber_decode_SEQUENCE(spki, spkisize, &temp, &temp_len, &spkisize);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -8741,8 +8743,10 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t *tokdata, SESSION *session,
|
|
object_put(tokdata, base_key_obj, TRUE);
|
|
base_key_obj = NULL;
|
|
} else {
|
|
- rc = ber_decode_OCTET_STRING(ecdh1_parms->pPublicData, &ecpoint,
|
|
- &ecpoint_len, &field_len);
|
|
+ rc = ber_decode_OCTET_STRING(ecdh1_parms->pPublicData,
|
|
+ ecdh1_parms->ulPublicDataLen,
|
|
+ &ecpoint, &ecpoint_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK || field_len != ecdh1_parms->ulPublicDataLen ||
|
|
ecpoint_len > ecdh1_parms->ulPublicDataLen - 2) {
|
|
/* no valid BER OCTET STRING encoding, assume raw */
|
|
@@ -9524,15 +9528,15 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t *tokdata,
|
|
#endif
|
|
|
|
/* CKA_VALUE of the public key must hold 'y' */
|
|
- rc = ber_decode_SPKI(publblob, &oid, &oid_len, &parm, &parm_len,
|
|
- &y_start, &bit_str_len);
|
|
+ rc = ber_decode_SPKI(publblob, publblobsize, &oid, &oid_len,
|
|
+ &parm, &parm_len, &y_start, &bit_str_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode SKPI failed rc=0x%lx\n", __func__, rc);
|
|
goto dh_generate_keypair_end;
|
|
}
|
|
|
|
/* DHPublicKey ::= INTEGER -- public key, y = g^x mod p */
|
|
- rc = ber_decode_INTEGER(y_start, &data, &data_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(y_start, bit_str_len, &data, &data_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_INTEGER failed rc=0x%lx\n", __func__, rc);
|
|
goto dh_generate_keypair_end;
|
|
@@ -9933,15 +9937,15 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t *tokdata,
|
|
}
|
|
|
|
/* set CKA_VALUE of the public key, first get key from SPKI */
|
|
- rc = ber_decode_SPKI(publblob, &oid, &oid_len, &parm, &parm_len,
|
|
- &key, &bit_str_len);
|
|
+ rc = ber_decode_SPKI(publblob, publblobsize, &oid, &oid_len,
|
|
+ &parm, &parm_len, &key, &bit_str_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s reading DSA SPKI failed with rc=0x%lx\n", __func__, rc);
|
|
goto dsa_generate_keypair_end;
|
|
}
|
|
|
|
/* key must be an integer */
|
|
- rc = ber_decode_INTEGER(key, &data, &data_len, &field_len);
|
|
+ rc = ber_decode_INTEGER(key, bit_str_len, &data, &data_len, &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s reading DSA public key failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -10214,7 +10218,7 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
TRACE_DEBUG("%s ec_generate_keypair spki:\n", __func__);
|
|
TRACE_DEBUG_DUMP(" ", spki, spki_len);
|
|
#endif
|
|
- rc = ber_decode_SPKI(spki, &oid, &oid_len, &parm, &parm_len,
|
|
+ rc = ber_decode_SPKI(spki, spki_len, &oid, &oid_len, &parm, &parm_len,
|
|
&key, &bit_str_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read key from SPKI failed with rc=0x%lx\n",
|
|
@@ -10310,8 +10314,9 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
* already built SPKI (in CKA_IBM_OPAQUE of the public key).
|
|
*/
|
|
CK_BYTE *modulus, *publ_exp;
|
|
+ CK_ULONG modulus_len, publ_exp_len;
|
|
|
|
- rc = ber_decode_SPKI(spki, &oid, &oid_len, &parm, &parm_len,
|
|
+ rc = ber_decode_SPKI(spki, spki_len, &oid, &oid_len, &parm, &parm_len,
|
|
&key, &bit_str_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read key from SPKI failed with rc=0x%lx\n",
|
|
@@ -10322,7 +10327,8 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
/* key must be a sequence holding two integers,
|
|
* modulus and public exponent
|
|
*/
|
|
- rc = ber_decode_SEQUENCE(key, &data, &data_len, &field_len);
|
|
+ rc = ber_decode_SEQUENCE(key, bit_str_len, &data, &data_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read sequence failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -10330,7 +10336,9 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
}
|
|
|
|
modulus = key + field_len - data_len;
|
|
- rc = ber_decode_INTEGER(modulus, &data, &data_len, &field_len);
|
|
+ modulus_len = bit_str_len - field_len + data_len;
|
|
+ rc = ber_decode_INTEGER(modulus, modulus_len, &data, &data_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read modulus failed with rc=0x%lx\n", __func__, rc);
|
|
goto error;
|
|
@@ -10357,7 +10365,9 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
|
|
|
|
/* read public exponent */
|
|
publ_exp = modulus + field_len;
|
|
- rc = ber_decode_INTEGER(publ_exp, &data, &data_len, &field_len);
|
|
+ publ_exp_len = bit_str_len - field_len;
|
|
+ rc = ber_decode_INTEGER(publ_exp, publ_exp_len, &data, &data_len,
|
|
+ &field_len);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s read public exponent failed with rc=0x%lx\n",
|
|
__func__, rc);
|
|
@@ -13929,7 +13939,7 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session,
|
|
}
|
|
|
|
/* csum is a MACed SPKI, get length of SPKI part only */
|
|
- rc = ber_decode_SEQUENCE(csum, &temp, &temp_len, &cslen);
|
|
+ rc = ber_decode_SEQUENCE(csum, cslen, &temp, &temp_len, &cslen);
|
|
if (rc != CKR_OK) {
|
|
TRACE_ERROR("%s ber_decode_SEQUENCE failed rc=0x%lx\n",
|
|
__func__, rc);
|
|
diff --git a/usr/lib/ica_s390_stdll/ica_specific.c b/usr/lib/ica_s390_stdll/ica_specific.c
|
|
index 005b3c19..192b1ea5 100644
|
|
--- a/usr/lib/ica_s390_stdll/ica_specific.c
|
|
+++ b/usr/lib/ica_s390_stdll/ica_specific.c
|
|
@@ -6244,8 +6244,8 @@ static CK_RV ica_build_ec_pub_key(OBJECT *key_obj, ICA_EC_KEY **eckey,
|
|
}
|
|
|
|
/* CKA_EC_POINT contains the EC point as OCTET STRING */
|
|
- ret = ber_decode_OCTET_STRING(attr->pValue, &ecpoint, &ecpoint_len,
|
|
- &field_len);
|
|
+ ret = ber_decode_OCTET_STRING(attr->pValue, attr->ulValueLen,
|
|
+ &ecpoint, &ecpoint_len, &field_len);
|
|
if (ret != CKR_OK || field_len != attr->ulValueLen) {
|
|
TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
|
|
ret = CKR_ATTRIBUTE_VALUE_INVALID;
|