Skip to content

Commit 581d939

Browse files
author
Emma Stensland
committed
added ml-dsa plain key and cert algorithms
1 parent a760b9a commit 581d939

10 files changed

Lines changed: 3077 additions & 83 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;
@@ -1533,6 +1604,11 @@ static int SetDefualtUserID(WOLFSSHD_AUTH* auth)
15331604
struct passwd* pwInfo;
15341605
int ret = WS_SUCCESS;
15351606

1607+
if (wolfSSHD_ConfigGetPrivilegeSeparation(auth->conf) ==
1608+
WOLFSSHD_PRIV_OFF) {
1609+
return WS_SUCCESS;
1610+
}
1611+
15361612
pwInfo = getpwnam(WOLFSSH_USER_STRING(WOLFSSH_SSHD_USER));
15371613
if (pwInfo == NULL) {
15381614
/* user name not found on system */
@@ -1625,24 +1701,30 @@ int wolfSSHD_AuthFreeUser(WOLFSSHD_AUTH* auth)
16251701
/* return WS_SUCCESS on success */
16261702
int wolfSSHD_AuthRaisePermissions(WOLFSSHD_AUTH* auth)
16271703
{
1628-
int ret = 0;
1704+
int ret = WS_SUCCESS;
16291705

1630-
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Attempting to raise permissions level");
16311706
#ifndef WIN32
1632-
if (auth) {
1633-
if (setegid(auth->sGid) != 0) {
1634-
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising gid");
1635-
ret = WS_FATAL_ERROR;
1707+
{
1708+
byte flag = 0;
1709+
1710+
if (!auth) {
1711+
return WS_BAD_ARGUMENT;
16361712
}
16371713

1638-
if (seteuid(auth->sUid) != 0) {
1639-
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising uid");
1640-
ret = WS_FATAL_ERROR;
1714+
flag = wolfSSHD_ConfigGetPrivilegeSeparation(auth->conf);
1715+
if (flag == WOLFSSHD_PRIV_SEPARAT || flag == WOLFSSHD_PRIV_SANDBOX) {
1716+
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Attempting to raise permissions level");
1717+
if (setegid(auth->sGid) != 0) {
1718+
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising gid");
1719+
ret = WS_FATAL_ERROR;
1720+
}
1721+
1722+
if (seteuid(auth->sUid) != 0) {
1723+
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error raising uid");
1724+
ret = WS_FATAL_ERROR;
1725+
}
16411726
}
16421727
}
1643-
else {
1644-
ret = WS_BAD_ARGUMENT;
1645-
}
16461728
#endif
16471729

16481730
return ret;

examples/echoserver/echoserver.c

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

17751775

1776+
#ifndef WOLFSSH_NO_MLDSA44
1777+
static int load_key_mldsa44(byte* buf, word32 bufSz)
1778+
{
1779+
word32 sz = 0;
1780+
#ifndef NO_FILESYSTEM
1781+
sz = load_file("./keys/server-key-mldsa44.der", buf, &bufSz);
1782+
#else
1783+
(void)buf; (void)bufSz;
1784+
#endif
1785+
return sz;
1786+
}
1787+
#endif /* WOLFSSH_NO_MLDSA44 */
1788+
1789+
#ifndef WOLFSSH_NO_MLDSA65
1790+
static int load_key_mldsa65(byte* buf, word32 bufSz)
1791+
{
1792+
word32 sz = 0;
1793+
#ifndef NO_FILESYSTEM
1794+
sz = load_file("./keys/server-key-mldsa65.der", buf, &bufSz);
1795+
#else
1796+
(void)buf; (void)bufSz;
1797+
#endif
1798+
return sz;
1799+
}
1800+
#endif /* WOLFSSH_NO_MLDSA65 */
1801+
1802+
#ifndef WOLFSSH_NO_MLDSA87
1803+
static int load_key_mldsa87(byte* buf, word32 bufSz)
1804+
{
1805+
word32 sz = 0;
1806+
#ifndef NO_FILESYSTEM
1807+
sz = load_file("./keys/server-key-mldsa87.der", buf, &bufSz);
1808+
#else
1809+
(void)buf; (void)bufSz;
1810+
#endif
1811+
return sz;
1812+
}
1813+
#endif /* WOLFSSH_NO_MLDSA87 */
1814+
1815+
17761816
typedef struct StrList {
17771817
const char* str;
17781818
struct StrList* next;
@@ -2294,6 +2334,7 @@ static int wsUserAuth(byte authType,
22942334
PwMapList* list;
22952335
PwMap* map;
22962336
byte authHash[WC_SHA256_DIGEST_SIZE];
2337+
int userFound = 0;
22972338

22982339
if (ctx == NULL) {
22992340
fprintf(stderr, "wsUserAuth: ctx not set");
@@ -2416,12 +2457,12 @@ static int wsUserAuth(byte authType,
24162457
authData->type == map->type) {
24172458

24182459
if (authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
2460+
userFound = 1;
24192461
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
24202462
return WOLFSSH_USERAUTH_SUCCESS;
24212463
}
2422-
else {
2423-
return WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
2424-
}
2464+
/* Hash mismatch: continue checking other registered keys
2465+
* for this user (a user may have multiple public keys). */
24252466
}
24262467
else if (authData->type == WOLFSSH_USERAUTH_PASSWORD) {
24272468
if (WMEMCMP(map->p, authHash, WC_SHA256_DIGEST_SIZE) == 0) {
@@ -2464,6 +2505,8 @@ static int wsUserAuth(byte authType,
24642505
map = map->next;
24652506
}
24662507

2508+
if (userFound)
2509+
return WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
24672510
return WOLFSSH_USERAUTH_INVALID_USER;
24682511
}
24692512

@@ -3002,6 +3045,64 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
30023045
}
30033046
#endif /* WOLFSSH_NO_ED25519 */
30043047

3048+
/* ML-DSA keys are loaded only when the key algo list explicitly
3049+
* includes an mldsa variant. They are larger than classical keys
3050+
* (~3900-4900 bytes) and sit at the top of the default canned list,
3051+
* so unconditionally loading them would shift negotiation to mldsa
3052+
* for all connections and break non-mldsa tests. */
3053+
#ifndef WOLFSSH_NO_MLDSA
3054+
if (keyList != NULL && WSTRSTR(keyList, "mldsa") != NULL) {
3055+
#define MLDSA_KEY_LOAD_BUF_SZ MLDSA_MAX_BOTH_KEY_DER_SIZE
3056+
byte* mldsaBuf = (byte*)WMALLOC(MLDSA_KEY_LOAD_BUF_SZ, NULL, 0);
3057+
if (mldsaBuf == NULL) {
3058+
ES_ERROR("Couldn't allocate ML-DSA key load buffer.\n");
3059+
}
3060+
else {
3061+
word32 mldsaSz;
3062+
const char* mldsaErrMsg = NULL;
3063+
3064+
#ifndef WOLFSSH_NO_MLDSA44
3065+
if (mldsaErrMsg == NULL) {
3066+
mldsaSz = load_key_mldsa44(mldsaBuf, MLDSA_KEY_LOAD_BUF_SZ);
3067+
if (mldsaSz == 0)
3068+
mldsaErrMsg = "Couldn't load ML-DSA-44 key file.\n";
3069+
else if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, mldsaBuf,
3070+
mldsaSz, WOLFSSH_FORMAT_ASN1) < 0)
3071+
mldsaErrMsg = "Couldn't use ML-DSA-44 key buffer.\n";
3072+
}
3073+
#endif /* WOLFSSH_NO_MLDSA44 */
3074+
3075+
#ifndef WOLFSSH_NO_MLDSA65
3076+
if (mldsaErrMsg == NULL) {
3077+
mldsaSz = load_key_mldsa65(mldsaBuf, MLDSA_KEY_LOAD_BUF_SZ);
3078+
if (mldsaSz == 0)
3079+
mldsaErrMsg = "Couldn't load ML-DSA-65 key file.\n";
3080+
else if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, mldsaBuf,
3081+
mldsaSz, WOLFSSH_FORMAT_ASN1) < 0)
3082+
mldsaErrMsg = "Couldn't use ML-DSA-65 key buffer.\n";
3083+
}
3084+
#endif /* WOLFSSH_NO_MLDSA65 */
3085+
3086+
#ifndef WOLFSSH_NO_MLDSA87
3087+
if (mldsaErrMsg == NULL) {
3088+
mldsaSz = load_key_mldsa87(mldsaBuf, MLDSA_KEY_LOAD_BUF_SZ);
3089+
if (mldsaSz == 0)
3090+
mldsaErrMsg = "Couldn't load ML-DSA-87 key file.\n";
3091+
else if (wolfSSH_CTX_UsePrivateKey_buffer(ctx, mldsaBuf,
3092+
mldsaSz, WOLFSSH_FORMAT_ASN1) < 0)
3093+
mldsaErrMsg = "Couldn't use ML-DSA-87 key buffer.\n";
3094+
}
3095+
#endif /* WOLFSSH_NO_MLDSA87 */
3096+
3097+
WFREE(mldsaBuf, NULL, 0);
3098+
if (mldsaErrMsg != NULL) {
3099+
ES_ERROR("%s", mldsaErrMsg);
3100+
}
3101+
}
3102+
#undef MLDSA_KEY_LOAD_BUF_SZ
3103+
}
3104+
#endif /* WOLFSSH_NO_MLDSA */
3105+
30053106
#ifndef NO_FILESYSTEM
30063107
if (userPubKey) {
30073108
byte* userBuf = NULL;

0 commit comments

Comments
 (0)