Skip to content

Commit 7602a43

Browse files
author
Emma Stensland
committed
added ml-dsa plain key and cert algorithms
1 parent 281e4bc commit 7602a43

10 files changed

Lines changed: 3080 additions & 86 deletions

File tree

apps/wolfsshd/auth.c

Lines changed: 97 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,12 @@ struct WOLFSSHD_AUTH {
105105
#endif
106106

107107
#ifndef MAX_LINE_SZ
108-
#define MAX_LINE_SZ 900
108+
/* Sized to hold the largest authorized_keys entry. */
109+
#ifndef WOLFSSH_NO_MLDSA
110+
#define MAX_LINE_SZ (WC_MLDSA_87_PUB_KEY_SIZE * 4 / 3 + 640)
111+
#else
112+
#define MAX_LINE_SZ 900
113+
#endif
109114
#endif
110115
#ifndef MAX_PATH_SZ
111116
#define MAX_PATH_SZ 80
@@ -174,11 +179,55 @@ static int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
174179
char* last = NULL;
175180

176181
enum {
182+
NUM_BASE_TYPES = 5,
177183
#ifdef WOLFSSH_CERTS
178-
NUM_ALLOWED_TYPES = 9
184+
NUM_CERT_TYPES = 4,
179185
#else
180-
NUM_ALLOWED_TYPES = 5
186+
NUM_CERT_TYPES = 0,
181187
#endif
188+
#ifndef WOLFSSH_NO_MLDSA
189+
#ifndef WOLFSSH_NO_MLDSA44
190+
MLDSA44_COUNT = 1,
191+
#else
192+
MLDSA44_COUNT = 0,
193+
#endif
194+
#ifndef WOLFSSH_NO_MLDSA65
195+
MLDSA65_COUNT = 1,
196+
#else
197+
MLDSA65_COUNT = 0,
198+
#endif
199+
#ifndef WOLFSSH_NO_MLDSA87
200+
MLDSA87_COUNT = 1,
201+
#else
202+
MLDSA87_COUNT = 0,
203+
#endif
204+
NUM_MLDSA_TYPES = MLDSA44_COUNT + MLDSA65_COUNT + MLDSA87_COUNT,
205+
#else
206+
NUM_MLDSA_TYPES = 0,
207+
#endif
208+
#if !defined(WOLFSSH_NO_MLDSA) && defined(WOLFSSH_CERTS)
209+
#ifndef WOLFSSH_NO_MLDSA44
210+
MLDSA44_CERT_COUNT = 1,
211+
#else
212+
MLDSA44_CERT_COUNT = 0,
213+
#endif
214+
#ifndef WOLFSSH_NO_MLDSA65
215+
MLDSA65_CERT_COUNT = 1,
216+
#else
217+
MLDSA65_CERT_COUNT = 0,
218+
#endif
219+
#ifndef WOLFSSH_NO_MLDSA87
220+
MLDSA87_CERT_COUNT = 1,
221+
#else
222+
MLDSA87_CERT_COUNT = 0,
223+
#endif
224+
NUM_MLDSA_CERT_TYPES = MLDSA44_CERT_COUNT + MLDSA65_CERT_COUNT +
225+
MLDSA87_CERT_COUNT,
226+
#else
227+
NUM_MLDSA_CERT_TYPES = 0,
228+
#endif
229+
NUM_ALLOWED_TYPES = NUM_BASE_TYPES + NUM_CERT_TYPES +
230+
NUM_MLDSA_TYPES + NUM_MLDSA_CERT_TYPES
182231
};
183232
static const char* allowedTypes[NUM_ALLOWED_TYPES] = {
184233
"ssh-rsa",
@@ -192,6 +241,28 @@ static int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
192241
"x509v3-ecdsa-sha2-nistp384",
193242
"x509v3-ecdsa-sha2-nistp521",
194243
#endif
244+
#ifndef WOLFSSH_NO_MLDSA
245+
#ifndef WOLFSSH_NO_MLDSA44
246+
"ssh-mldsa-44",
247+
#endif
248+
#ifndef WOLFSSH_NO_MLDSA65
249+
"ssh-mldsa-65",
250+
#endif
251+
#ifndef WOLFSSH_NO_MLDSA87
252+
"ssh-mldsa-87",
253+
#endif
254+
#ifdef WOLFSSH_CERTS
255+
#ifndef WOLFSSH_NO_MLDSA44
256+
"x509v3-ssh-mldsa-44",
257+
#endif
258+
#ifndef WOLFSSH_NO_MLDSA65
259+
"x509v3-ssh-mldsa-65",
260+
#endif
261+
#ifndef WOLFSSH_NO_MLDSA87
262+
"x509v3-ssh-mldsa-87",
263+
#endif
264+
#endif
265+
#endif
195266
};
196267
int typeOk = 0;
197268
int i;
@@ -1573,6 +1644,11 @@ static int SetDefualtUserID(WOLFSSHD_AUTH* auth)
15731644
struct passwd* pwInfo;
15741645
int ret = WS_SUCCESS;
15751646

1647+
if (wolfSSHD_ConfigGetPrivilegeSeparation(auth->conf) ==
1648+
WOLFSSHD_PRIV_OFF) {
1649+
return WS_SUCCESS;
1650+
}
1651+
15761652
pwInfo = getpwnam(WOLFSSH_USER_STRING(WOLFSSH_SSHD_USER));
15771653
if (pwInfo == NULL) {
15781654
/* user name not found on system */
@@ -1665,24 +1741,30 @@ int wolfSSHD_AuthFreeUser(WOLFSSHD_AUTH* auth)
16651741
/* return WS_SUCCESS on success */
16661742
int wolfSSHD_AuthRaisePermissions(WOLFSSHD_AUTH* auth)
16671743
{
1668-
int ret = 0;
1744+
int ret = WS_SUCCESS;
16691745

1670-
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Attempting to raise permissions level");
16711746
#ifndef WIN32
1672-
if (auth) {
1673-
if (setegid(auth->sGid) != 0) {
1674-
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising gid");
1675-
ret = WS_FATAL_ERROR;
1747+
{
1748+
byte flag = 0;
1749+
1750+
if (!auth) {
1751+
return WS_BAD_ARGUMENT;
16761752
}
16771753

1678-
if (seteuid(auth->sUid) != 0) {
1679-
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising uid");
1680-
ret = WS_FATAL_ERROR;
1754+
flag = wolfSSHD_ConfigGetPrivilegeSeparation(auth->conf);
1755+
if (flag == WOLFSSHD_PRIV_SEPARAT || flag == WOLFSSHD_PRIV_SANDBOX) {
1756+
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Attempting to raise permissions level");
1757+
if (setegid(auth->sGid) != 0) {
1758+
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising gid");
1759+
ret = WS_FATAL_ERROR;
1760+
}
1761+
1762+
if (seteuid(auth->sUid) != 0) {
1763+
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising uid");
1764+
ret = WS_FATAL_ERROR;
1765+
}
16811766
}
16821767
}
1683-
else {
1684-
ret = WS_BAD_ARGUMENT;
1685-
}
16861768
#endif
16871769

16881770
return ret;

examples/echoserver/echoserver.c

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,6 +1777,46 @@ static int load_key_ed25519(byte* buf, word32 bufSz)
17771777
#endif /* WOLFSSH_NO_ED25519 */
17781778

17791779

1780+
#ifndef WOLFSSH_NO_MLDSA44
1781+
static int load_key_mldsa44(byte* buf, word32 bufSz)
1782+
{
1783+
word32 sz = 0;
1784+
#ifndef NO_FILESYSTEM
1785+
sz = load_file("./keys/server-key-mldsa44.der", buf, &bufSz);
1786+
#else
1787+
(void)buf; (void)bufSz;
1788+
#endif
1789+
return sz;
1790+
}
1791+
#endif /* WOLFSSH_NO_MLDSA44 */
1792+
1793+
#ifndef WOLFSSH_NO_MLDSA65
1794+
static int load_key_mldsa65(byte* buf, word32 bufSz)
1795+
{
1796+
word32 sz = 0;
1797+
#ifndef NO_FILESYSTEM
1798+
sz = load_file("./keys/server-key-mldsa65.der", buf, &bufSz);
1799+
#else
1800+
(void)buf; (void)bufSz;
1801+
#endif
1802+
return sz;
1803+
}
1804+
#endif /* WOLFSSH_NO_MLDSA65 */
1805+
1806+
#ifndef WOLFSSH_NO_MLDSA87
1807+
static int load_key_mldsa87(byte* buf, word32 bufSz)
1808+
{
1809+
word32 sz = 0;
1810+
#ifndef NO_FILESYSTEM
1811+
sz = load_file("./keys/server-key-mldsa87.der", buf, &bufSz);
1812+
#else
1813+
(void)buf; (void)bufSz;
1814+
#endif
1815+
return sz;
1816+
}
1817+
#endif /* WOLFSSH_NO_MLDSA87 */
1818+
1819+
17801820
typedef struct StrList {
17811821
const char* str;
17821822
struct StrList* next;
@@ -2410,6 +2450,7 @@ static int wsUserAuth(byte authType,
24102450
PwMapList* list;
24112451
PwMap* map;
24122452
byte authHash[WC_SHA256_DIGEST_SIZE] = {0};
2453+
int userFound = 0;
24132454

24142455
if (ctx == NULL) {
24152456
fprintf(stderr, "wsUserAuth: ctx not set");
@@ -2530,12 +2571,12 @@ static int wsUserAuth(byte authType,
25302571
authData->type == map->type) {
25312572

25322573
if (authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
2574+
userFound = 1;
25332575
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
25342576
return WOLFSSH_USERAUTH_SUCCESS;
25352577
}
2536-
else {
2537-
return WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
2538-
}
2578+
/* Hash mismatch: continue checking other registered keys
2579+
* for this user (a user may have multiple public keys). */
25392580
}
25402581
else if (authData->type == WOLFSSH_USERAUTH_PASSWORD) {
25412582
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
@@ -2578,6 +2619,8 @@ static int wsUserAuth(byte authType,
25782619
map = map->next;
25792620
}
25802621

2622+
if (userFound)
2623+
return WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
25812624
return WOLFSSH_USERAUTH_INVALID_USER;
25822625
}
25832626

@@ -3151,6 +3194,64 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
31513194
#endif /* WOLFSSH_NO_ED25519 */
31523195
}
31533196

3197+
/* ML-DSA keys are loaded only when the key algo list explicitly
3198+
* includes an mldsa variant. They are larger than classical keys
3199+
* (~3900-4900 bytes) and sit at the top of the default canned list,
3200+
* so unconditionally loading them would shift negotiation to mldsa
3201+
* for all connections and break non-mldsa tests. */
3202+
#ifndef WOLFSSH_NO_MLDSA
3203+
if (keyList != NULL && WSTRSTR(keyList, "mldsa") != NULL) {
3204+
#define MLDSA_KEY_LOAD_BUF_SZ MLDSA_MAX_BOTH_KEY_DER_SIZE
3205+
byte* mldsaBuf = (byte*)WMALLOC(MLDSA_KEY_LOAD_BUF_SZ, NULL, 0);
3206+
if (mldsaBuf == NULL) {
3207+
ES_ERROR("Couldn't allocate ML-DSA key load buffer.\n");
3208+
}
3209+
else {
3210+
word32 mldsaSz;
3211+
const char* mldsaErrMsg = NULL;
3212+
3213+
#ifndef WOLFSSH_NO_MLDSA44
3214+
if (mldsaErrMsg == NULL) {
3215+
mldsaSz = load_key_mldsa44(mldsaBuf, MLDSA_KEY_LOAD_BUF_SZ);
3216+
if (mldsaSz == 0)
3217+
mldsaErrMsg = "Couldn't load ML-DSA-44 key file.\n";
3218+
else if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, mldsaBuf,
3219+
mldsaSz, WOLFSSH_FORMAT_ASN1) < 0)
3220+
mldsaErrMsg = "Couldn't use ML-DSA-44 key buffer.\n";
3221+
}
3222+
#endif /* WOLFSSH_NO_MLDSA44 */
3223+
3224+
#ifndef WOLFSSH_NO_MLDSA65
3225+
if (mldsaErrMsg == NULL) {
3226+
mldsaSz = load_key_mldsa65(mldsaBuf, MLDSA_KEY_LOAD_BUF_SZ);
3227+
if (mldsaSz == 0)
3228+
mldsaErrMsg = "Couldn't load ML-DSA-65 key file.\n";
3229+
else if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, mldsaBuf,
3230+
mldsaSz, WOLFSSH_FORMAT_ASN1) < 0)
3231+
mldsaErrMsg = "Couldn't use ML-DSA-65 key buffer.\n";
3232+
}
3233+
#endif /* WOLFSSH_NO_MLDSA65 */
3234+
3235+
#ifndef WOLFSSH_NO_MLDSA87
3236+
if (mldsaErrMsg == NULL) {
3237+
mldsaSz = load_key_mldsa87(mldsaBuf, MLDSA_KEY_LOAD_BUF_SZ);
3238+
if (mldsaSz == 0)
3239+
mldsaErrMsg = "Couldn't load ML-DSA-87 key file.\n";
3240+
else if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, mldsaBuf,
3241+
mldsaSz, WOLFSSH_FORMAT_ASN1) < 0)
3242+
mldsaErrMsg = "Couldn't use ML-DSA-87 key buffer.\n";
3243+
}
3244+
#endif /* WOLFSSH_NO_MLDSA87 */
3245+
3246+
WFREE(mldsaBuf, NULL, 0);
3247+
if (mldsaErrMsg != NULL) {
3248+
ES_ERROR("%s", mldsaErrMsg);
3249+
}
3250+
}
3251+
#undef MLDSA_KEY_LOAD_BUF_SZ
3252+
}
3253+
#endif /* WOLFSSH_NO_MLDSA */
3254+
31543255
#ifndef NO_FILESYSTEM
31553256
if (userPubKey) {
31563257
byte* userBuf = NULL;

0 commit comments

Comments
 (0)