Skip to content

Commit ec6c705

Browse files
authored
Merge pull request #7928 from dgarske/riscv_fixes
Fixes for building on RISC-V
2 parents 4d837e7 + b7a6c6c commit ec6c705

5 files changed

Lines changed: 129 additions & 124 deletions

File tree

src/include.am

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -992,14 +992,13 @@ src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/blake2s.c
992992
endif
993993

994994
if BUILD_CHACHA
995+
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/chacha.c
995996
if BUILD_ARMASM_NEON
996997
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/arm/armv8-chacha.c
997998
else
998999
if BUILD_RISCV_ASM
9991000
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/port/riscv/riscv-64-chacha.c
1000-
else
1001-
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/chacha.c
1002-
endif !BUILD_RISCV_ASM
1001+
endif BUILD_RISCV_ASM
10031002
if !BUILD_X86_ASM
10041003
if BUILD_INTELASM
10051004
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/chacha_asm.S

wolfcrypt/src/chacha.c

Lines changed: 122 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,56 @@ Public domain.
3535

3636
#include <wolfssl/wolfcrypt/settings.h>
3737

38+
#ifdef HAVE_CHACHA
39+
#include <wolfssl/wolfcrypt/chacha.h>
40+
#include <wolfssl/wolfcrypt/error-crypt.h>
41+
42+
#ifdef NO_INLINE
43+
#include <wolfssl/wolfcrypt/misc.h>
44+
#else
45+
#define WOLFSSL_MISC_INCLUDED
46+
#include <wolfcrypt/src/misc.c>
47+
#endif
48+
49+
#ifdef BIG_ENDIAN_ORDER
50+
#define LITTLE32(x) ByteReverseWord32(x)
51+
#else
52+
#define LITTLE32(x) (x)
53+
#endif
54+
55+
/* Number of rounds */
56+
#define ROUNDS 20
57+
58+
#define U32C(v) (v##U)
59+
#define U32V(v) ((word32)(v) & U32C(0xFFFFFFFF))
60+
#define U8TO32_LITTLE(p) LITTLE32(((word32*)(p))[0])
61+
62+
#define ROTATE(v,c) rotlFixed(v, c)
63+
#define XOR(v,w) ((v) ^ (w))
64+
#define PLUS(v,w) (U32V((v) + (w)))
65+
#define PLUSONE(v) (PLUS((v),1))
66+
67+
#define QUARTERROUND(a,b,c,d) \
68+
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \
69+
x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \
70+
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \
71+
x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);
72+
#endif /* HAVE_CHACHA */
73+
74+
3875
#if defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_ARMASM_NO_NEON)
3976
/* implementation is located in wolfcrypt/src/port/arm/armv8-chacha.c */
4077

4178
#elif defined(WOLFSSL_RISCV_ASM)
4279
/* implementation located in wolfcrypt/src/port/rsicv/riscv-64-chacha.c */
4380

4481
#else
82+
83+
/* BEGIN ChaCha C implementation */
4584
#if defined(HAVE_CHACHA)
4685

47-
#include <wolfssl/wolfcrypt/chacha.h>
48-
#include <wolfssl/wolfcrypt/error-crypt.h>
4986
#include <wolfssl/wolfcrypt/logging.h>
5087
#include <wolfssl/wolfcrypt/cpuid.h>
51-
#ifdef NO_INLINE
52-
#include <wolfssl/wolfcrypt/misc.h>
53-
#else
54-
#define WOLFSSL_MISC_INCLUDED
55-
#include <wolfcrypt/src/misc.c>
56-
#endif
5788

5889
#ifdef CHACHA_AEAD_TEST
5990
#include <stdio.h>
@@ -88,31 +119,6 @@ Public domain.
88119
static word32 cpuidFlags = 0;
89120
#endif
90121

91-
#ifdef BIG_ENDIAN_ORDER
92-
#define LITTLE32(x) ByteReverseWord32(x)
93-
#else
94-
#define LITTLE32(x) (x)
95-
#endif
96-
97-
/* Number of rounds */
98-
#define ROUNDS 20
99-
100-
#define U32C(v) (v##U)
101-
#define U32V(v) ((word32)(v) & U32C(0xFFFFFFFF))
102-
#define U8TO32_LITTLE(p) LITTLE32(((word32*)(p))[0])
103-
104-
#define ROTATE(v,c) rotlFixed(v, c)
105-
#define XOR(v,w) ((v) ^ (w))
106-
#define PLUS(v,w) (U32V((v) + (w)))
107-
#define PLUSONE(v) (PLUS((v),1))
108-
109-
#define QUARTERROUND(a,b,c,d) \
110-
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \
111-
x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \
112-
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \
113-
x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);
114-
115-
116122
/**
117123
* Set up iv(nonce). Earlier versions used 64 bits instead of 96, this version
118124
* uses the typical AEAD 96 bit nonce and can do record sizes of 256 GB.
@@ -238,86 +244,6 @@ static WC_INLINE void wc_Chacha_wordtobyte(word32 x[CHACHA_CHUNK_WORDS],
238244
}
239245
#endif /* !USE_INTEL_CHACHA_SPEEDUP */
240246

241-
242-
#ifdef HAVE_XCHACHA
243-
244-
/*
245-
* wc_HChacha_block - half a ChaCha block, for XChaCha
246-
*
247-
* see https://tools.ietf.org/html/draft-arciszewski-xchacha-03
248-
*/
249-
static WC_INLINE void wc_HChacha_block(ChaCha* ctx, word32 stream[CHACHA_CHUNK_WORDS/2], word32 nrounds)
250-
{
251-
word32 x[CHACHA_CHUNK_WORDS];
252-
word32 i;
253-
254-
for (i = 0; i < CHACHA_CHUNK_WORDS; i++) {
255-
x[i] = ctx->X[i];
256-
}
257-
258-
for (i = nrounds; i > 0; i -= 2) {
259-
QUARTERROUND(0, 4, 8, 12)
260-
QUARTERROUND(1, 5, 9, 13)
261-
QUARTERROUND(2, 6, 10, 14)
262-
QUARTERROUND(3, 7, 11, 15)
263-
QUARTERROUND(0, 5, 10, 15)
264-
QUARTERROUND(1, 6, 11, 12)
265-
QUARTERROUND(2, 7, 8, 13)
266-
QUARTERROUND(3, 4, 9, 14)
267-
}
268-
269-
for (i = 0; i < CHACHA_CHUNK_WORDS/4; ++i)
270-
stream[i] = x[i];
271-
for (i = CHACHA_CHUNK_WORDS/4; i < CHACHA_CHUNK_WORDS/2; ++i)
272-
stream[i] = x[i + CHACHA_CHUNK_WORDS/2];
273-
}
274-
275-
/* XChaCha -- https://tools.ietf.org/html/draft-arciszewski-xchacha-03 */
276-
int wc_XChacha_SetKey(ChaCha *ctx,
277-
const byte *key, word32 keySz,
278-
const byte *nonce, word32 nonceSz,
279-
word32 counter) {
280-
word32 k[CHACHA_MAX_KEY_SZ];
281-
byte iv[CHACHA_IV_BYTES];
282-
int ret;
283-
284-
if (nonceSz != XCHACHA_NONCE_BYTES)
285-
return BAD_FUNC_ARG;
286-
287-
if ((ret = wc_Chacha_SetKey(ctx, key, keySz)) < 0)
288-
return ret;
289-
290-
/* form a first chacha IV from the first 16 bytes of the nonce.
291-
* the first word is supplied in the "counter" arg, and
292-
* the result is a full 128 bit nonceful IV for the one-time block
293-
* crypto op that follows.
294-
*/
295-
if ((ret = wc_Chacha_SetIV(ctx, nonce + 4, U8TO32_LITTLE(nonce))) < 0)
296-
return ret;
297-
298-
wc_HChacha_block(ctx, k, 20); /* 20 rounds, but keeping half the output. */
299-
300-
/* the HChacha output is used as a 256 bit key for the main cipher. */
301-
XMEMCPY(&ctx->X[4], k, 8 * sizeof(word32));
302-
303-
/* use 8 bytes from the end of the 24 byte nonce, padded up to 12 bytes,
304-
* to form the IV for the main cipher.
305-
*/
306-
XMEMSET(iv, 0, 4);
307-
XMEMCPY(iv + 4, nonce + 16, 8);
308-
309-
if ((ret = wc_Chacha_SetIV(ctx, iv, counter)) < 0)
310-
return ret;
311-
312-
ForceZero(k, sizeof k);
313-
ForceZero(iv, sizeof iv);
314-
315-
return 0;
316-
}
317-
318-
#endif /* HAVE_XCHACHA */
319-
320-
321247
#ifdef __cplusplus
322248
extern "C" {
323249
#endif
@@ -441,14 +367,94 @@ int wc_Chacha_Process(ChaCha* ctx, byte* output, const byte* input,
441367
#endif
442368
}
443369

444-
void wc_Chacha_purge_current_block(ChaCha* ctx) {
370+
#endif /* HAVE_CHACHA */
371+
#endif /* END ChaCha C implementation */
372+
373+
#if defined(HAVE_CHACHA) && defined(HAVE_XCHACHA)
374+
375+
void wc_Chacha_purge_current_block(ChaCha* ctx)
376+
{
445377
if (ctx->left > 0) {
446378
byte scratch[CHACHA_CHUNK_BYTES];
447379
XMEMSET(scratch, 0, sizeof(scratch));
448380
(void)wc_Chacha_Process(ctx, scratch, scratch, CHACHA_CHUNK_BYTES - ctx->left);
449381
}
450382
}
451383

452-
#endif /* HAVE_CHACHA */
384+
/*
385+
* wc_HChacha_block - half a ChaCha block, for XChaCha
386+
*
387+
* see https://tools.ietf.org/html/draft-arciszewski-xchacha-03
388+
*/
389+
static WC_INLINE void wc_HChacha_block(ChaCha* ctx,
390+
word32 stream[CHACHA_CHUNK_WORDS/2], word32 nrounds)
391+
{
392+
word32 x[CHACHA_CHUNK_WORDS];
393+
word32 i;
394+
395+
for (i = 0; i < CHACHA_CHUNK_WORDS; i++) {
396+
x[i] = ctx->X[i];
397+
}
398+
399+
for (i = nrounds; i > 0; i -= 2) {
400+
QUARTERROUND(0, 4, 8, 12)
401+
QUARTERROUND(1, 5, 9, 13)
402+
QUARTERROUND(2, 6, 10, 14)
403+
QUARTERROUND(3, 7, 11, 15)
404+
QUARTERROUND(0, 5, 10, 15)
405+
QUARTERROUND(1, 6, 11, 12)
406+
QUARTERROUND(2, 7, 8, 13)
407+
QUARTERROUND(3, 4, 9, 14)
408+
}
409+
410+
for (i = 0; i < CHACHA_CHUNK_WORDS/4; ++i)
411+
stream[i] = x[i];
412+
for (i = CHACHA_CHUNK_WORDS/4; i < CHACHA_CHUNK_WORDS/2; ++i)
413+
stream[i] = x[i + CHACHA_CHUNK_WORDS/2];
414+
}
415+
416+
/* XChaCha -- https://tools.ietf.org/html/draft-arciszewski-xchacha-03 */
417+
int wc_XChacha_SetKey(ChaCha *ctx,
418+
const byte *key, word32 keySz,
419+
const byte *nonce, word32 nonceSz,
420+
word32 counter)
421+
{
422+
int ret;
423+
word32 k[CHACHA_MAX_KEY_SZ];
424+
byte iv[CHACHA_IV_BYTES];
425+
426+
if (nonceSz != XCHACHA_NONCE_BYTES)
427+
return BAD_FUNC_ARG;
428+
429+
if ((ret = wc_Chacha_SetKey(ctx, key, keySz)) < 0)
430+
return ret;
431+
432+
/* form a first chacha IV from the first 16 bytes of the nonce.
433+
* the first word is supplied in the "counter" arg, and
434+
* the result is a full 128 bit nonceful IV for the one-time block
435+
* crypto op that follows.
436+
*/
437+
if ((ret = wc_Chacha_SetIV(ctx, nonce + 4, U8TO32_LITTLE(nonce))) < 0)
438+
return ret;
439+
440+
wc_HChacha_block(ctx, k, 20); /* 20 rounds, but keeping half the output. */
441+
442+
/* the HChacha output is used as a 256 bit key for the main cipher. */
443+
XMEMCPY(&ctx->X[4], k, 8 * sizeof(word32));
444+
445+
/* use 8 bytes from the end of the 24 byte nonce, padded up to 12 bytes,
446+
* to form the IV for the main cipher.
447+
*/
448+
XMEMSET(iv, 0, 4);
449+
XMEMCPY(iv + 4, nonce + 16, 8);
450+
451+
if ((ret = wc_Chacha_SetIV(ctx, iv, counter)) < 0)
452+
return ret;
453+
454+
ForceZero(k, sizeof k);
455+
ForceZero(iv, sizeof iv);
456+
457+
return 0;
458+
}
453459

454-
#endif /* WOLFSSL_ARMASM && !WOLFSSL_ARMASM_NO_NEON */
460+
#endif /* HAVE_CHACHA && HAVE_XCHACHA */

wolfcrypt/src/port/riscv/riscv-64-sha512.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ int wc_Sha512Transform(wc_Sha512* sha512, const unsigned char* data)
12161216
ret = BAD_FUNC_ARG;
12171217
}
12181218
else {
1219-
ByteReverseWords(sha512->buffer, (word32*)data, WC_SHA512_BLOCK_SIZE);
1219+
ByteReverseWords((word32*)sha512->buffer, (word32*)data, WC_SHA512_BLOCK_SIZE);
12201220
Sha512Transform(sha512, (byte*)sha512->buffer, 1);
12211221
}
12221222

wolfssl/wolfcrypt/chacha.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ WOLFSSL_API int wc_Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter);
9797
WOLFSSL_API int wc_Chacha_Process(ChaCha* ctx, byte* cipher, const byte* plain,
9898
word32 msglen);
9999

100-
WOLFSSL_LOCAL void wc_Chacha_purge_current_block(ChaCha* ctx);
101-
102100
WOLFSSL_API int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz);
103101

104102
#ifdef HAVE_XCHACHA
103+
WOLFSSL_LOCAL void wc_Chacha_purge_current_block(ChaCha* ctx);
104+
105105
WOLFSSL_API int wc_XChacha_SetKey(ChaCha *ctx, const byte *key, word32 keySz,
106106
const byte *nonce, word32 nonceSz,
107107
word32 counter);

wolfssl/wolfcrypt/settings.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3281,8 +3281,8 @@ extern void uITRON4_free(void *p) ;
32813281
#define WOLFSSL_NO_HASH_RAW
32823282
#endif
32833283

3284-
/* XChacha not implemented with ARM assembly ChaCha */
3285-
#if defined(WOLFSSL_ARMASM)
3284+
#if defined(HAVE_XCHACHA) && !defined(HAVE_CHACHA)
3285+
/* XChacha requires ChaCha */
32863286
#undef HAVE_XCHACHA
32873287
#endif
32883288

0 commit comments

Comments
 (0)