This commit is contained in:
Willy-JL
2023-08-11 22:54:16 +02:00
parent 35cf740a63
commit 12004d0ef4
18 changed files with 1877 additions and 2070 deletions

View File

@@ -58,64 +58,50 @@ static uint32_t RCON[10]; // AES round constants
* Platform Endianness Neutralizing Load and Store Macro definitions
* AES wants platform-neutral Little Endian (LE) byte ordering
*/
#define GET_UINT32_LE(n,b,i) { \
(n) = ( (uint32_t) (b)[(i) ] ) \
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
| ( (uint32_t) (b)[(i) + 3] << 24 ); }
#define GET_UINT32_LE(n, b, i) \
{ \
(n) = ((uint32_t)(b)[(i)]) | ((uint32_t)(b)[(i) + 1] << 8) | \
((uint32_t)(b)[(i) + 2] << 16) | ((uint32_t)(b)[(i) + 3] << 24); \
}
#define PUT_UINT32_LE(n,b,i) { \
#define PUT_UINT32_LE(n, b, i) \
{ \
(b)[(i)] = (uchar)((n)); \
(b)[(i) + 1] = (uchar)((n) >> 8); \
(b)[(i) + 2] = (uchar)((n) >> 16); \
(b)[(i) + 3] = (uchar) ( (n) >> 24 ); }
(b)[(i) + 3] = (uchar)((n) >> 24); \
}
/*
* AES forward and reverse encryption round processing macros
*/
#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
{ \
X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \
FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
X0 = *RK++ ^ FT0[(Y0)&0xFF] ^ FT1[(Y1 >> 8) & 0xFF] ^ FT2[(Y2 >> 16) & 0xFF] ^ \
FT3[(Y3 >> 24) & 0xFF]; \
\
X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \
FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
X1 = *RK++ ^ FT0[(Y1)&0xFF] ^ FT1[(Y2 >> 8) & 0xFF] ^ FT2[(Y3 >> 16) & 0xFF] ^ \
FT3[(Y0 >> 24) & 0xFF]; \
\
X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \
FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
X2 = *RK++ ^ FT0[(Y2)&0xFF] ^ FT1[(Y3 >> 8) & 0xFF] ^ FT2[(Y0 >> 16) & 0xFF] ^ \
FT3[(Y1 >> 24) & 0xFF]; \
\
X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \
FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
X3 = *RK++ ^ FT0[(Y3)&0xFF] ^ FT1[(Y0 >> 8) & 0xFF] ^ FT2[(Y1 >> 16) & 0xFF] ^ \
FT3[(Y2 >> 24) & 0xFF]; \
}
#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
{ \
X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \
RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
X0 = *RK++ ^ RT0[(Y0)&0xFF] ^ RT1[(Y3 >> 8) & 0xFF] ^ RT2[(Y2 >> 16) & 0xFF] ^ \
RT3[(Y1 >> 24) & 0xFF]; \
\
X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \
RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
X1 = *RK++ ^ RT0[(Y1)&0xFF] ^ RT1[(Y0 >> 8) & 0xFF] ^ RT2[(Y3 >> 16) & 0xFF] ^ \
RT3[(Y2 >> 24) & 0xFF]; \
\
X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \
RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
X2 = *RK++ ^ RT0[(Y2)&0xFF] ^ RT1[(Y1 >> 8) & 0xFF] ^ RT2[(Y0 >> 16) & 0xFF] ^ \
RT3[(Y3 >> 24) & 0xFF]; \
\
X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \
RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
X3 = *RK++ ^ RT0[(Y3)&0xFF] ^ RT1[(Y2 >> 8) & 0xFF] ^ RT2[(Y1 >> 16) & 0xFF] ^ \
RT3[(Y0 >> 24) & 0xFF]; \
}
@@ -127,9 +113,18 @@ static uint32_t RCON[10]; // AES round constants
#define ROTL8(x) ((x << 8) & 0xFFFFFFFF) | (x >> 24)
#define XTIME(x) ((x << 1) ^ ((x & 0x80) ? 0x1B : 0x00))
#define MUL(x, y) ((x && y) ? pow[(log[x] + log[y]) % 255] : 0)
#define MIX(x,y) { y = ( (y << 1) | (y >> 7) ) & 0xFF; x ^= y; }
#define CPY128 { *RK++ = *SK++; *RK++ = *SK++; \
*RK++ = *SK++; *RK++ = *SK++; }
#define MIX(x, y) \
{ \
y = ((y << 1) | (y >> 7)) & 0xFF; \
x ^= y; \
}
#define CPY128 \
{ \
*RK++ = *SK++; \
*RK++ = *SK++; \
*RK++ = *SK++; \
*RK++ = *SK++; \
}
/******************************************************************************
*
@@ -141,8 +136,7 @@ static uint32_t RCON[10]; // AES round constants
* at system initialization to setup the tables for all subsequent use.
*
******************************************************************************/
void aes_init_keygen_tables( void )
{
void aes_init_keygen_tables(void) {
int i, x, y, z; // general purpose iteration and computation locals
int pow[256];
int log[256];
@@ -176,7 +170,6 @@ void aes_init_keygen_tables( void )
#if AES_DECRYPTION // whether AES decryption is supported
RSb[x] = (uchar)i;
#endif /* AES_DECRYPTION */
}
// generate the forward and reverse key expansion tables
for(i = 0; i < 256; i++) {
@@ -184,8 +177,7 @@ void aes_init_keygen_tables( void )
y = XTIME(x) & 0xFF;
z = (y ^ x) & 0xFF;
FT0[i] = ( (uint32_t) y ) ^ ( (uint32_t) x << 8 ) ^
( (uint32_t) x << 16 ) ^ ( (uint32_t) z << 24 );
FT0[i] = ((uint32_t)y) ^ ((uint32_t)x << 8) ^ ((uint32_t)x << 16) ^ ((uint32_t)z << 24);
FT1[i] = ROTL8(FT0[i]);
FT2[i] = ROTL8(FT1[i]);
@@ -194,10 +186,8 @@ void aes_init_keygen_tables( void )
#if AES_DECRYPTION // whether AES decryption is supported
x = RSb[i];
RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
( (uint32_t) MUL( 0x09, x ) << 8 ) ^
( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
( (uint32_t) MUL( 0x0B, x ) << 24 );
RT0[i] = ((uint32_t)MUL(0x0E, x)) ^ ((uint32_t)MUL(0x09, x) << 8) ^
((uint32_t)MUL(0x0D, x) << 16) ^ ((uint32_t)MUL(0x0B, x) << 24);
RT1[i] = ROTL8(RT0[i]);
RT2[i] = ROTL8(RT1[i]);
@@ -217,10 +207,7 @@ void aes_init_keygen_tables( void )
* Valid lengths are: 16, 24 or 32 bytes (128, 192, 256 bits).
*
******************************************************************************/
int aes_set_encryption_key( aes_context *ctx,
const uchar *key,
uint keysize )
{
int aes_set_encryption_key(aes_context* ctx, const uchar* key, uint keysize) {
uint i; // general purpose iteration local
uint32_t* RK = ctx->rk; // initialize our RoundKey buffer pointer
@@ -228,12 +215,10 @@ int aes_set_encryption_key( aes_context *ctx,
GET_UINT32_LE(RK[i], key, i << 2);
}
switch( ctx->rounds )
{
switch(ctx->rounds) {
case 10:
for(i = 0; i < 10; i++, RK += 4) {
RK[4] = RK[0] ^ RCON[i] ^
( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
RK[4] = RK[0] ^ RCON[i] ^ ((uint32_t)FSb[(RK[3] >> 8) & 0xFF]) ^
((uint32_t)FSb[(RK[3] >> 16) & 0xFF] << 8) ^
((uint32_t)FSb[(RK[3] >> 24) & 0xFF] << 16) ^
((uint32_t)FSb[(RK[3]) & 0xFF] << 24);
@@ -246,8 +231,7 @@ int aes_set_encryption_key( aes_context *ctx,
case 12:
for(i = 0; i < 8; i++, RK += 6) {
RK[6] = RK[0] ^ RCON[i] ^
( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
RK[6] = RK[0] ^ RCON[i] ^ ((uint32_t)FSb[(RK[5] >> 8) & 0xFF]) ^
((uint32_t)FSb[(RK[5] >> 16) & 0xFF] << 8) ^
((uint32_t)FSb[(RK[5] >> 24) & 0xFF] << 16) ^
((uint32_t)FSb[(RK[5]) & 0xFF] << 24);
@@ -262,8 +246,7 @@ int aes_set_encryption_key( aes_context *ctx,
case 14:
for(i = 0; i < 7; i++, RK += 8) {
RK[8] = RK[0] ^ RCON[i] ^
( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
RK[8] = RK[0] ^ RCON[i] ^ ((uint32_t)FSb[(RK[7] >> 8) & 0xFF]) ^
((uint32_t)FSb[(RK[7] >> 16) & 0xFF] << 8) ^
((uint32_t)FSb[(RK[7] >> 24) & 0xFF] << 16) ^
((uint32_t)FSb[(RK[7]) & 0xFF] << 24);
@@ -272,8 +255,7 @@ int aes_set_encryption_key( aes_context *ctx,
RK[10] = RK[2] ^ RK[9];
RK[11] = RK[3] ^ RK[10];
RK[12] = RK[4] ^
( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
RK[12] = RK[4] ^ ((uint32_t)FSb[(RK[11]) & 0xFF]) ^
((uint32_t)FSb[(RK[11] >> 8) & 0xFF] << 8) ^
((uint32_t)FSb[(RK[11] >> 16) & 0xFF] << 16) ^
((uint32_t)FSb[(RK[11] >> 24) & 0xFF] << 24);
@@ -302,10 +284,7 @@ int aes_set_encryption_key( aes_context *ctx,
* length in bits. Valid lengths are: 128, 192, or 256 bits.
*
******************************************************************************/
int aes_set_decryption_key( aes_context *ctx,
const uchar *key,
uint keysize )
{
int aes_set_decryption_key(aes_context* ctx, const uchar* key, uint keysize) {
int i, j;
aes_context cty; // a calling aes context for set_encryption_key
uint32_t* RK = ctx->rk; // initialize our RoundKey buffer pointer
@@ -315,8 +294,7 @@ int aes_set_decryption_key( aes_context *ctx,
cty.rounds = ctx->rounds; // initialize our local aes context
cty.rk = cty.buf; // round count and key buf pointer
if (( ret = aes_set_encryption_key( &cty, key, keysize )) != 0 )
return( ret );
if((ret = aes_set_encryption_key(&cty, key, keysize)) != 0) return (ret);
SK = cty.rk + cty.rounds * 4;
@@ -324,10 +302,8 @@ int aes_set_decryption_key( aes_context *ctx,
for(i = ctx->rounds - 1, SK -= 8; i > 0; i--, SK -= 8) {
for(j = 0; j < 4; j++, SK++) {
*RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
*RK++ = RT0[FSb[(*SK) & 0xFF]] ^ RT1[FSb[(*SK >> 8) & 0xFF]] ^
RT2[FSb[(*SK >> 16) & 0xFF]] ^ RT3[FSb[(*SK >> 24) & 0xFF]];
}
}
CPY128 // copy a 128-bit block from *SK to *RK
@@ -344,7 +320,8 @@ int aes_set_decryption_key( aes_context *ctx,
* Invoked to establish the key schedule for subsequent encryption/decryption
*
******************************************************************************/
int aes_setkey( aes_context *ctx, // AES context provided by our caller
int aes_setkey(
aes_context* ctx, // AES context provided by our caller
int mode, // ENCRYPT or DECRYPT flag
const uchar* key, // pointer to the key
uint keysize) // key length in bytes
@@ -360,10 +337,17 @@ int aes_setkey( aes_context *ctx, // AES context provided by our caller
switch(keysize) // set the rounds count based upon the keysize
{
case 16: ctx->rounds = 10; break; // 16-byte, 128-bit key
case 24: ctx->rounds = 12; break; // 24-byte, 192-bit key
case 32: ctx->rounds = 14; break; // 32-byte, 256-bit key
default: return(-1);
case 16:
ctx->rounds = 10;
break; // 16-byte, 128-bit key
case 24:
ctx->rounds = 12;
break; // 24-byte, 192-bit key
case 32:
ctx->rounds = 14;
break; // 32-byte, 256-bit key
default:
return (-1);
}
#if AES_DECRYPTION
@@ -383,91 +367,64 @@ int aes_setkey( aes_context *ctx, // AES context provided by our caller
* and all keying information appropriate for the task.
*
******************************************************************************/
int aes_cipher( aes_context *ctx,
const uchar input[16],
uchar output[16] )
{
int aes_cipher(aes_context* ctx, const uchar input[16], uchar output[16]) {
int i;
uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; // general purpose locals
RK = ctx->rk;
GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; // load our 128-bit
GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; // input buffer in a storage
GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; // memory endian-neutral way
GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
GET_UINT32_LE(X0, input, 0);
X0 ^= *RK++; // load our 128-bit
GET_UINT32_LE(X1, input, 4);
X1 ^= *RK++; // input buffer in a storage
GET_UINT32_LE(X2, input, 8);
X2 ^= *RK++; // memory endian-neutral way
GET_UINT32_LE(X3, input, 12);
X3 ^= *RK++;
#if AES_DECRYPTION // whether AES decryption is supported
if( ctx->mode == DECRYPT )
{
for( i = (ctx->rounds >> 1) - 1; i > 0; i-- )
{
if(ctx->mode == DECRYPT) {
for(i = (ctx->rounds >> 1) - 1; i > 0; i--) {
AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);
}
AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
X0 = *RK++ ^ \
( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
X0 = *RK++ ^ ((uint32_t)RSb[(Y0)&0xFF]) ^ ((uint32_t)RSb[(Y3 >> 8) & 0xFF] << 8) ^
((uint32_t)RSb[(Y2 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y1 >> 24) & 0xFF] << 24);
X1 = *RK++ ^ \
( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
X1 = *RK++ ^ ((uint32_t)RSb[(Y1)&0xFF]) ^ ((uint32_t)RSb[(Y0 >> 8) & 0xFF] << 8) ^
((uint32_t)RSb[(Y3 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y2 >> 24) & 0xFF] << 24);
X2 = *RK++ ^ \
( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
X2 = *RK++ ^ ((uint32_t)RSb[(Y2)&0xFF]) ^ ((uint32_t)RSb[(Y1 >> 8) & 0xFF] << 8) ^
((uint32_t)RSb[(Y0 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y3 >> 24) & 0xFF] << 24);
X3 = *RK++ ^ \
( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
}
else /* ENCRYPT */
X3 = *RK++ ^ ((uint32_t)RSb[(Y3)&0xFF]) ^ ((uint32_t)RSb[(Y2 >> 8) & 0xFF] << 8) ^
((uint32_t)RSb[(Y1 >> 16) & 0xFF] << 16) ^ ((uint32_t)RSb[(Y0 >> 24) & 0xFF] << 24);
} else /* ENCRYPT */
{
#endif /* AES_DECRYPTION */
for( i = (ctx->rounds >> 1) - 1; i > 0; i-- )
{
for(i = (ctx->rounds >> 1) - 1; i > 0; i--) {
AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);
}
AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
X0 = *RK++ ^ \
( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
X0 = *RK++ ^ ((uint32_t)FSb[(Y0)&0xFF]) ^ ((uint32_t)FSb[(Y1 >> 8) & 0xFF] << 8) ^
((uint32_t)FSb[(Y2 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y3 >> 24) & 0xFF] << 24);
X1 = *RK++ ^ \
( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
X1 = *RK++ ^ ((uint32_t)FSb[(Y1)&0xFF]) ^ ((uint32_t)FSb[(Y2 >> 8) & 0xFF] << 8) ^
((uint32_t)FSb[(Y3 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y0 >> 24) & 0xFF] << 24);
X2 = *RK++ ^ \
( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
X2 = *RK++ ^ ((uint32_t)FSb[(Y2)&0xFF]) ^ ((uint32_t)FSb[(Y3 >> 8) & 0xFF] << 8) ^
((uint32_t)FSb[(Y0 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y1 >> 24) & 0xFF] << 24);
X3 = *RK++ ^ \
( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
X3 = *RK++ ^ ((uint32_t)FSb[(Y3)&0xFF]) ^ ((uint32_t)FSb[(Y0 >> 8) & 0xFF] << 8) ^
((uint32_t)FSb[(Y1 >> 16) & 0xFF] << 16) ^ ((uint32_t)FSb[(Y2 >> 24) & 0xFF] << 24);
#if AES_DECRYPTION // whether AES decryption is supported
}

View File

@@ -42,13 +42,11 @@
typedef unsigned char uchar; // add some convienent shorter types
typedef unsigned int uint;
/******************************************************************************
* AES_INIT_KEYGEN_TABLES : MUST be called once before any AES use
******************************************************************************/
void aes_init_keygen_tables(void);
/******************************************************************************
* AES_CONTEXT : cipher context / holds inter-call data
******************************************************************************/
@@ -59,11 +57,11 @@ typedef struct {
uint32_t buf[68]; // key expansion buffer
} aes_context;
/******************************************************************************
* AES_SETKEY : called to expand the key for encryption or decryption
******************************************************************************/
int aes_setkey( aes_context *ctx, // pointer to context
int aes_setkey(
aes_context* ctx, // pointer to context
int mode, // 1 or 0 for Encrypt/Decrypt
const uchar* key, // AES input key
uint keysize); // size in bytes (must be 16, 24, 32 for
@@ -73,7 +71,8 @@ int aes_setkey( aes_context *ctx, // pointer to context
/******************************************************************************
* AES_CIPHER : called to encrypt or decrypt ONE 128-bit block of data
******************************************************************************/
int aes_cipher( aes_context *ctx, // pointer to context
int aes_cipher(
aes_context* ctx, // pointer to context
const uchar input[16], // 128-bit block to en/decipher
uchar output[16]); // 128-bit output result block
// returns 0 for success

View File

@@ -76,25 +76,40 @@
* significantly slower 128x128 bit multiple within GF(2^128).
*/
static const uint64_t last4[16] = {
0x0000, 0x1c20, 0x3840, 0x2460, 0x7080, 0x6ca0, 0x48c0, 0x54e0,
0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0 };
0x0000,
0x1c20,
0x3840,
0x2460,
0x7080,
0x6ca0,
0x48c0,
0x54e0,
0xe100,
0xfd20,
0xd940,
0xc560,
0x9180,
0x8da0,
0xa9c0,
0xb5e0};
/*
* Platform Endianness Neutralizing Load and Store Macro definitions
* GCM wants platform-neutral Big Endian (BE) byte ordering
*/
#define GET_UINT32_BE(n,b,i) { \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); }
#define GET_UINT32_BE(n, b, i) \
{ \
(n) = ((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | \
((uint32_t)(b)[(i) + 2] << 8) | ((uint32_t)(b)[(i) + 3]); \
}
#define PUT_UINT32_BE(n,b,i) { \
#define PUT_UINT32_BE(n, b, i) \
{ \
(b)[(i)] = (uchar)((n) >> 24); \
(b)[(i) + 1] = (uchar)((n) >> 16); \
(b)[(i) + 2] = (uchar)((n) >> 8); \
(b)[(i) + 3] = (uchar) ( (n) ); }
(b)[(i) + 3] = (uchar)((n)); \
}
/******************************************************************************
*
@@ -108,13 +123,11 @@ static const uint64_t last4[16] = {
* environment is running.
*
******************************************************************************/
int gcm_initialize( void )
{
int gcm_initialize(void) {
aes_init_keygen_tables();
return (0);
}
/******************************************************************************
*
* GCM_MULT
@@ -124,7 +137,8 @@ int gcm_initialize( void )
* 'x' and 'output' are seen as elements of GCM's GF(2^128) Galois field.
*
******************************************************************************/
static void gcm_mult( gcm_context *ctx, // pointer to established context
static void gcm_mult(
gcm_context* ctx, // pointer to established context
const uchar x[16], // pointer to 128-bit input vector
uchar output[16]) // pointer to 128-bit output vector
{
@@ -162,7 +176,6 @@ static void gcm_mult( gcm_context *ctx, // pointer to established context
PUT_UINT32_BE(zl, output, 12);
}
/******************************************************************************
*
* GCM_SETKEY
@@ -171,7 +184,8 @@ static void gcm_mult( gcm_context *ctx, // pointer to established context
* and populates the gcm context's pre-calculated HTables.
*
******************************************************************************/
int gcm_setkey( gcm_context *ctx, // pointer to caller-provided gcm context
int gcm_setkey(
gcm_context* ctx, // pointer to caller-provided gcm context
const uchar* key, // pointer to the AES encryption key
const uint keysize) // size in bytes (must be 16, 24, 32 for
// 128, 192 or 256-bit keys respectively)
@@ -186,10 +200,8 @@ int gcm_setkey( gcm_context *ctx, // pointer to caller-provided gcm context
// encrypt the null 128-bit block to generate a key-based value
// which is then used to initialize our GHASH lookup tables
if(( ret = aes_setkey( &ctx->aes_ctx, ENCRYPT, key, keysize )) != 0 )
return( ret );
if(( ret = aes_cipher( &ctx->aes_ctx, h, h )) != 0 )
return( ret );
if((ret = aes_setkey(&ctx->aes_ctx, ENCRYPT, key, keysize)) != 0) return (ret);
if((ret = aes_cipher(&ctx->aes_ctx, h, h)) != 0) return (ret);
GET_UINT32_BE(hi, h, 0); // pack h as two 64-bit ints, big-endian
GET_UINT32_BE(lo, h, 4);
@@ -223,7 +235,6 @@ int gcm_setkey( gcm_context *ctx, // pointer to caller-provided gcm context
return (0);
}
/******************************************************************************
*
* GCM processing occurs four phases: SETKEY, START, UPDATE and FINISH.
@@ -245,7 +256,8 @@ int gcm_setkey( gcm_context *ctx, // pointer to caller-provided gcm context
* mode, and preprocesses the initialization vector and additional AEAD data.
*
******************************************************************************/
int gcm_start( gcm_context *ctx, // pointer to user-provided GCM context
int gcm_start(
gcm_context* ctx, // pointer to user-provided GCM context
int mode, // GCM_ENCRYPT or GCM_DECRYPT
const uchar* iv, // pointer to initialization vector
size_t iv_len, // IV length in bytes (should == 12)
@@ -271,8 +283,7 @@ int gcm_start( gcm_context *ctx, // pointer to user-provided GCM context
if(iv_len == 12) { // GCM natively uses a 12-byte, 96-bit IV
memcpy(ctx->y, iv, iv_len); // copy the IV to the top of the 'y' buff
ctx->y[15] = 1; // start "counting" from 1 (not 0)
}
else // if we don't have a 12-byte IV, we GHASH whatever we've been given
} else // if we don't have a 12-byte IV, we GHASH whatever we've been given
{
memset(work_buf, 0x00, 16); // clear the working buffer
PUT_UINT32_BE(iv_len * 8, work_buf, 12); // place the IV into buffer
@@ -288,8 +299,7 @@ int gcm_start( gcm_context *ctx, // pointer to user-provided GCM context
for(i = 0; i < 16; i++) ctx->y[i] ^= work_buf[i];
gcm_mult(ctx, ctx->y, ctx->y);
}
if( ( ret = aes_cipher( &ctx->aes_ctx, ctx->y, ctx->base_ectr ) ) != 0 )
return( ret );
if((ret = aes_cipher(&ctx->aes_ctx, ctx->y, ctx->base_ectr)) != 0) return (ret);
ctx->add_len = add_len;
p = add;
@@ -314,7 +324,8 @@ int gcm_start( gcm_context *ctx, // pointer to user-provided GCM context
* have a partial block length of < 128 bits.)
*
******************************************************************************/
int gcm_update( gcm_context *ctx, // pointer to user-provided GCM context
int gcm_update(
gcm_context* ctx, // pointer to user-provided GCM context
size_t length, // length, in bytes, of data to process
const uchar* input, // pointer to source data
uchar* output) // pointer to destination data
@@ -331,15 +342,14 @@ int gcm_update( gcm_context *ctx, // pointer to user-provided GCM context
use_len = (length < 16) ? length : 16;
// increment the context's 128-bit IV||Counter 'y' vector
for( i = 16; i > 12; i-- ) if( ++ctx->y[i - 1] != 0 ) break;
for(i = 16; i > 12; i--)
if(++ctx->y[i - 1] != 0) break;
// encrypt the context's 'y' vector under the established key
if( ( ret = aes_cipher( &ctx->aes_ctx, ctx->y, ectr ) ) != 0 )
return( ret );
if((ret = aes_cipher(&ctx->aes_ctx, ctx->y, ectr)) != 0) return (ret);
// encrypt or decrypt the input to the output
if( ctx->mode == ENCRYPT )
{
if(ctx->mode == ENCRYPT) {
for(i = 0; i < use_len; i++) {
// XOR the cipher's ouptut vector (ectr) with our input
output[i] = (uchar)(ectr[i] ^ input[i]);
@@ -349,9 +359,7 @@ int gcm_update( gcm_context *ctx, // pointer to user-provided GCM context
// data
ctx->buf[i] ^= output[i];
}
}
else
{
} else {
for(i = 0; i < use_len; i++) {
// but if we're DEcrypting we XOR in the input data first,
// i.e. before saving to ouput data, otherwise if the input
@@ -381,7 +389,8 @@ int gcm_update( gcm_context *ctx, // pointer to user-provided GCM context
* It performs the final GHASH to produce the resulting authentication TAG.
*
******************************************************************************/
int gcm_finish( gcm_context *ctx, // pointer to user-provided GCM context
int gcm_finish(
gcm_context* ctx, // pointer to user-provided GCM context
uchar* tag, // pointer to buffer which receives the tag
size_t tag_len) // length, in bytes, of the tag-receiving buf
{
@@ -407,7 +416,6 @@ int gcm_finish( gcm_context *ctx, // pointer to user-provided GCM context
return (0);
}
/******************************************************************************
*
* GCM_CRYPT_AND_TAG
@@ -448,7 +456,6 @@ int gcm_crypt_and_tag(
return (0);
}
/******************************************************************************
*
* GCM_AUTH_DECRYPT
@@ -481,12 +488,11 @@ int gcm_auth_decrypt(
(which is an identical XORing to reverse the previous one)
and also to re-generate the matching authentication tag
*/
gcm_crypt_and_tag( ctx, DECRYPT, iv, iv_len, add, add_len,
input, output, length, check_tag, tag_len );
gcm_crypt_and_tag(
ctx, DECRYPT, iv, iv_len, add, add_len, input, output, length, check_tag, tag_len);
// now we verify the authentication tag in 'constant time'
for( diff = 0, i = 0; i < tag_len; i++ )
diff |= tag[i] ^ check_tag[i];
for(diff = 0, i = 0; i < tag_len; i++) diff |= tag[i] ^ check_tag[i];
if(diff != 0) { // see whether any bits differed?
memset(output, 0, length); // if so... wipe the output data
@@ -504,8 +510,7 @@ int gcm_auth_decrypt(
* sensitive, so it MUST be zeroed after use. This function does that.
*
******************************************************************************/
void gcm_zero_ctx( gcm_context *ctx )
{
void gcm_zero_ctx(gcm_context* ctx) {
// zero the context originally provided to us
memset(ctx, 0, sizeof(gcm_context));
}

View File

@@ -37,7 +37,6 @@
#include <stdint.h>
#endif
/******************************************************************************
* GCM_CONTEXT : GCM context / holds keytables, instance data, and AES ctx
******************************************************************************/
@@ -53,23 +52,21 @@ typedef struct {
aes_context aes_ctx; // cipher context used
} gcm_context;
/******************************************************************************
* GCM_CONTEXT : MUST be called once before ANY use of this library
******************************************************************************/
int gcm_initialize(void);
/******************************************************************************
* GCM_SETKEY : sets the GCM (and AES) keying material for use
******************************************************************************/
int gcm_setkey( gcm_context *ctx, // caller-provided context ptr
int gcm_setkey(
gcm_context* ctx, // caller-provided context ptr
const uchar* key, // pointer to cipher key
const uint keysize // size in bytes (must be 16, 24, 32 for
// 128, 192 or 256-bit keys respectively)
); // returns 0 for success
/******************************************************************************
*
* GCM_CRYPT_AND_TAG
@@ -100,7 +97,6 @@ int gcm_crypt_and_tag(
uchar* tag, // pointer to the tag to be generated
size_t tag_len); // byte length of the tag to be generated
/******************************************************************************
*
* GCM_AUTH_DECRYPT
@@ -125,7 +121,6 @@ int gcm_auth_decrypt(
const uchar* tag, // pointer to the tag to be authenticated
size_t tag_len); // byte length of the tag <= 16
/******************************************************************************
*
* GCM_START
@@ -134,14 +129,14 @@ int gcm_auth_decrypt(
* mode, and preprocesses the initialization vector and additional AEAD data.
*
******************************************************************************/
int gcm_start( gcm_context *ctx, // pointer to user-provided GCM context
int gcm_start(
gcm_context* ctx, // pointer to user-provided GCM context
int mode, // ENCRYPT (1) or DECRYPT (0)
const uchar* iv, // pointer to initialization vector
size_t iv_len, // IV length in bytes (should == 12)
const uchar* add, // pointer to additional AEAD data (NULL if none)
size_t add_len); // length of additional AEAD data (bytes)
/******************************************************************************
*
* GCM_UPDATE
@@ -153,12 +148,12 @@ int gcm_start( gcm_context *ctx, // pointer to user-provided GCM context
* have a partial block length of < 128 bits.)
*
******************************************************************************/
int gcm_update( gcm_context *ctx, // pointer to user-provided GCM context
int gcm_update(
gcm_context* ctx, // pointer to user-provided GCM context
size_t length, // length, in bytes, of data to process
const uchar* input, // pointer to source data
uchar* output); // pointer to destination data
/******************************************************************************
*
* GCM_FINISH
@@ -167,11 +162,11 @@ int gcm_update( gcm_context *ctx, // pointer to user-provided GCM context
* It performs the final GHASH to produce the resulting authentication TAG.
*
******************************************************************************/
int gcm_finish( gcm_context *ctx, // pointer to user-provided GCM context
int gcm_finish(
gcm_context* ctx, // pointer to user-provided GCM context
uchar* tag, // ptr to tag buffer - NULL if tag_len = 0
size_t tag_len); // length, in bytes, of the tag-receiving buf
/******************************************************************************
*
* GCM_ZERO_CTX
@@ -183,5 +178,4 @@ int gcm_finish( gcm_context *ctx, // pointer to user-provided GCM context
******************************************************************************/
void gcm_zero_ctx(gcm_context* ctx);
#endif /* GCM_HEADER */

View File

@@ -28,22 +28,19 @@ struct ESubGhzChatCryptoMsg {
uint8_t data[0];
} __attribute__((packed));
void crypto_init(void)
{
void crypto_init(void) {
#ifndef FURI_HAL_CRYPTO_ADVANCED_AVAIL
/* init the GCM and AES tables */
gcm_initialize();
#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
}
void crypto_explicit_bzero(void *s, size_t len)
{
void crypto_explicit_bzero(void* s, size_t len) {
memset(s, 0, len);
asm volatile("" ::: "memory");
}
ESubGhzChatCryptoCtx *crypto_ctx_alloc(void)
{
ESubGhzChatCryptoCtx* crypto_ctx_alloc(void) {
ESubGhzChatCryptoCtx* ret = malloc(sizeof(ESubGhzChatCryptoCtx));
if(ret != NULL) {
@@ -56,15 +53,13 @@ ESubGhzChatCryptoCtx *crypto_ctx_alloc(void)
return ret;
}
void crypto_ctx_free(ESubGhzChatCryptoCtx *ctx)
{
void crypto_ctx_free(ESubGhzChatCryptoCtx* ctx) {
crypto_ctx_clear(ctx);
ESubGhzChatReplayDict_clear(ctx->replay_dict);
free(ctx);
}
void crypto_ctx_clear(ESubGhzChatCryptoCtx *ctx)
{
void crypto_ctx_clear(ESubGhzChatCryptoCtx* ctx) {
crypto_explicit_bzero(ctx->key, sizeof(ctx->key));
#ifndef FURI_HAL_CRYPTO_ADVANCED_AVAIL
crypto_explicit_bzero(&(ctx->gcm_ctx), sizeof(ctx->gcm_ctx));
@@ -74,8 +69,7 @@ void crypto_ctx_clear(ESubGhzChatCryptoCtx *ctx)
ctx->counter = 1;
}
static uint64_t crypto_calc_run_id(FuriString *flipper_name, uint32_t tick)
{
static uint64_t crypto_calc_run_id(FuriString* flipper_name, uint32_t tick) {
const char* fn = furi_string_get_cstr(flipper_name);
size_t fn_len = strlen(fn);
@@ -92,9 +86,11 @@ static uint64_t crypto_calc_run_id(FuriString *flipper_name, uint32_t tick)
return run_id;
}
bool crypto_ctx_set_key(ESubGhzChatCryptoCtx *ctx, const uint8_t *key,
FuriString *flipper_name, uint32_t tick)
{
bool crypto_ctx_set_key(
ESubGhzChatCryptoCtx* ctx,
const uint8_t* key,
FuriString* flipper_name,
uint32_t tick) {
ctx->run_id = crypto_calc_run_id(flipper_name, tick);
ctx->counter = 1;
@@ -106,14 +102,11 @@ bool crypto_ctx_set_key(ESubGhzChatCryptoCtx *ctx, const uint8_t *key,
#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
}
void crypto_ctx_get_key(ESubGhzChatCryptoCtx *ctx, uint8_t *key)
{
void crypto_ctx_get_key(ESubGhzChatCryptoCtx* ctx, uint8_t* key) {
memcpy(key, ctx->key, KEY_BITS / 8);
}
bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx *ctx, uint8_t *in, size_t in_len,
uint8_t *out)
{
bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out) {
if(in_len < MSG_OVERHEAD + 1) {
return false;
}
@@ -121,8 +114,7 @@ bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx *ctx, uint8_t *in, size_t in_len,
struct ESubGhzChatCryptoMsg* msg = (struct ESubGhzChatCryptoMsg*)in;
// check if message is stale, if yes, discard
uint32_t *counter = ESubGhzChatReplayDict_get(ctx->replay_dict,
msg->run_id);
uint32_t* counter = ESubGhzChatReplayDict_get(ctx->replay_dict, msg->run_id);
if(counter != NULL) {
if(*counter >= __ntohl(msg->counter)) {
return false;
@@ -131,33 +123,40 @@ bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx *ctx, uint8_t *in, size_t in_len,
// decrypt and auth message
#ifdef FURI_HAL_CRYPTO_ADVANCED_AVAIL
bool ret = (furi_hal_crypto_gcm_decrypt_and_verify(ctx->key,
bool ret =
(furi_hal_crypto_gcm_decrypt_and_verify(
ctx->key,
msg->iv,
(uint8_t *) msg, RUN_ID_BYTES + COUNTER_BYTES,
msg->data, out,
(uint8_t*)msg,
RUN_ID_BYTES + COUNTER_BYTES,
msg->data,
out,
in_len - MSG_OVERHEAD,
msg->tag) == FuriHalCryptoGCMStateOk);
#else /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
bool ret = (gcm_auth_decrypt(&(ctx->gcm_ctx),
msg->iv, IV_BYTES,
(uint8_t *) msg, RUN_ID_BYTES + COUNTER_BYTES,
msg->data, out,
bool ret =
(gcm_auth_decrypt(
&(ctx->gcm_ctx),
msg->iv,
IV_BYTES,
(uint8_t*)msg,
RUN_ID_BYTES + COUNTER_BYTES,
msg->data,
out,
in_len - MSG_OVERHEAD,
msg->tag, TAG_BYTES) == 0);
msg->tag,
TAG_BYTES) == 0);
#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
// if auth was successful update replay dict
if(ret) {
ESubGhzChatReplayDict_set_at(ctx->replay_dict, msg->run_id,
__ntohl(msg->counter));
ESubGhzChatReplayDict_set_at(ctx->replay_dict, msg->run_id, __ntohl(msg->counter));
}
return ret;
}
bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx *ctx, uint8_t *in, size_t in_len,
uint8_t *out)
{
bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out) {
struct ESubGhzChatCryptoMsg* msg = (struct ESubGhzChatCryptoMsg*)out;
// fill message header
@@ -167,19 +166,30 @@ bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx *ctx, uint8_t *in, size_t in_len,
// encrypt message and store tag in header
#ifdef FURI_HAL_CRYPTO_ADVANCED_AVAIL
bool ret = (furi_hal_crypto_gcm_encrypt_and_tag(ctx->key,
bool ret =
(furi_hal_crypto_gcm_encrypt_and_tag(
ctx->key,
msg->iv,
(uint8_t *) msg, RUN_ID_BYTES + COUNTER_BYTES,
in, msg->data,
(uint8_t*)msg,
RUN_ID_BYTES + COUNTER_BYTES,
in,
msg->data,
in_len,
msg->tag) == FuriHalCryptoGCMStateOk);
#else /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
bool ret = (gcm_crypt_and_tag(&(ctx->gcm_ctx), ENCRYPT,
msg->iv, IV_BYTES,
(uint8_t *) msg, RUN_ID_BYTES + COUNTER_BYTES,
in, msg->data,
bool ret =
(gcm_crypt_and_tag(
&(ctx->gcm_ctx),
ENCRYPT,
msg->iv,
IV_BYTES,
(uint8_t*)msg,
RUN_ID_BYTES + COUNTER_BYTES,
in,
msg->data,
in_len,
msg->tag, TAG_BYTES) == 0);
msg->tag,
TAG_BYTES) == 0);
#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
// increase internal counter

View File

@@ -24,14 +24,15 @@ void crypto_ctx_free(ESubGhzChatCryptoCtx *ctx);
void crypto_ctx_clear(ESubGhzChatCryptoCtx* ctx);
bool crypto_ctx_set_key(ESubGhzChatCryptoCtx *ctx, const uint8_t *key,
FuriString *flipper_name, uint32_t tick);
bool crypto_ctx_set_key(
ESubGhzChatCryptoCtx* ctx,
const uint8_t* key,
FuriString* flipper_name,
uint32_t tick);
void crypto_ctx_get_key(ESubGhzChatCryptoCtx* ctx, uint8_t* key);
bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx *ctx, uint8_t *in, size_t in_len,
uint8_t *out);
bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx *ctx, uint8_t *in, size_t in_len,
uint8_t *out);
bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out);
bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out);
#ifdef __cplusplus
}

View File

@@ -15,8 +15,7 @@
/* Callback for RX events from the Sub-GHz worker. Records the current ticks as
* the time of the last reception. */
static void have_read_cb(void* context)
{
static void have_read_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
@@ -25,20 +24,17 @@ static void have_read_cb(void* context)
/* Sets the header for the chat input field depending on whether or not a
* message preview exists. */
void set_chat_input_header(ESubGhzChatState *state)
{
void set_chat_input_header(ESubGhzChatState* state) {
if(strlen(state->msg_preview) == 0) {
text_input_set_header_text(state->text_input, "Message");
} else {
text_input_set_header_text(state->text_input,
state->msg_preview);
text_input_set_header_text(state->text_input, state->msg_preview);
}
}
/* Appends the latest message to the chat box and prepares the message preview.
*/
void append_msg(ESubGhzChatState *state, const char *msg)
{
void append_msg(ESubGhzChatState* state, const char* msg) {
/* append message to text box */
furi_string_cat_printf(state->chat_box_store, "\n%s", msg);
@@ -48,17 +44,14 @@ void append_msg(ESubGhzChatState *state, const char *msg)
set_chat_input_header(state);
/* reset text box contents and focus */
text_box_set_text(state->chat_box,
furi_string_get_cstr(state->chat_box_store));
text_box_set_text(state->chat_box, furi_string_get_cstr(state->chat_box_store));
text_box_set_focus(state->chat_box, TextBoxFocusEnd);
}
/* Decrypts a message for post_rx(). */
static bool post_rx_decrypt(ESubGhzChatState *state, size_t rx_size)
{
bool ret = crypto_ctx_decrypt(state->crypto_ctx,
state->rx_buffer, rx_size,
(uint8_t*) state->rx_str_buffer);
static bool post_rx_decrypt(ESubGhzChatState* state, size_t rx_size) {
bool ret = crypto_ctx_decrypt(
state->crypto_ctx, state->rx_buffer, rx_size, (uint8_t*)state->rx_str_buffer);
if(ret) {
state->rx_str_buffer[rx_size - (MSG_OVERHEAD)] = 0;
@@ -70,8 +63,7 @@ static bool post_rx_decrypt(ESubGhzChatState *state, size_t rx_size)
}
/* Post RX handler, decrypts received messages and calls append_msg(). */
static void post_rx(ESubGhzChatState *state, size_t rx_size)
{
static void post_rx(ESubGhzChatState* state, size_t rx_size) {
furi_assert(state);
if(rx_size == 0) {
@@ -106,8 +98,7 @@ static void post_rx(ESubGhzChatState *state, size_t rx_size)
/* Reads the message from msg_input, encrypts it if necessary and then
* transmits it. */
void tx_msg_input(ESubGhzChatState *state)
{
void tx_msg_input(ESubGhzChatState* state) {
/* encrypt message if necessary */
size_t msg_len = strlen(furi_string_get_cstr(state->msg_input));
size_t tx_size = msg_len;
@@ -115,17 +106,15 @@ void tx_msg_input(ESubGhzChatState *state)
tx_size += MSG_OVERHEAD;
furi_check(tx_size <= sizeof(state->tx_buffer));
crypto_ctx_encrypt(state->crypto_ctx,
(uint8_t *)
furi_string_get_cstr(state->msg_input),
crypto_ctx_encrypt(
state->crypto_ctx,
(uint8_t*)furi_string_get_cstr(state->msg_input),
msg_len,
state->tx_buffer);
} else {
tx_size += 2;
furi_check(tx_size <= sizeof(state->tx_buffer));
memcpy(state->tx_buffer,
furi_string_get_cstr(state->msg_input),
msg_len);
memcpy(state->tx_buffer, furi_string_get_cstr(state->msg_input), msg_len);
/* append \r\n for compat with Sub-GHz CLI chat */
state->tx_buffer[msg_len] = '\r';
@@ -133,20 +122,17 @@ void tx_msg_input(ESubGhzChatState *state)
}
/* transmit */
subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer,
tx_size);
subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer, tx_size);
}
/* Displays whether or not encryption has been enabled in the text box. Also
* clears the text input buffer to remove the password and starts the Sub-GHz
* worker. After starting the worker a join message is transmitted. */
void enter_chat(ESubGhzChatState *state)
{
furi_string_cat_printf(state->chat_box_store, "\nEncrypted: %s",
(state->encrypted ? "yes" : "no"));
void enter_chat(ESubGhzChatState* state) {
furi_string_cat_printf(
state->chat_box_store, "\nEncrypted: %s", (state->encrypted ? "yes" : "no"));
subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device,
state->frequency);
subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device, state->frequency);
/* concatenate the name prefix and join message */
furi_string_set(state->msg_input, state->name_prefix);
@@ -160,8 +146,7 @@ void enter_chat(ESubGhzChatState *state)
}
/* Sends a leave message */
void exit_chat(ESubGhzChatState *state)
{
void exit_chat(ESubGhzChatState* state) {
/* concatenate the name prefix and leave message */
furi_string_set(state->msg_input, state->name_prefix);
furi_string_cat_str(state->msg_input, " left chat.");
@@ -177,14 +162,12 @@ void exit_chat(ESubGhzChatState *state)
}
/* Whether or not to display the locked message. */
static bool kbd_lock_msg_display(ESubGhzChatState *state)
{
static bool kbd_lock_msg_display(ESubGhzChatState* state) {
return (state->kbd_lock_msg_ticks != 0);
}
/* Whether or not to hide the locked message again. */
static bool kbd_lock_msg_reset_timeout(ESubGhzChatState *state)
{
static bool kbd_lock_msg_reset_timeout(ESubGhzChatState* state) {
if(state->kbd_lock_msg_ticks == 0) {
return false;
}
@@ -198,34 +181,29 @@ static bool kbd_lock_msg_reset_timeout(ESubGhzChatState *state)
/* Resets the timeout for the locked message and turns off the backlight if
* specified. */
static void kbd_lock_msg_reset(ESubGhzChatState *state, bool backlight_off)
{
static void kbd_lock_msg_reset(ESubGhzChatState* state, bool backlight_off) {
state->kbd_lock_msg_ticks = 0;
state->kbd_lock_count = 0;
if(backlight_off) {
notification_message(state->notification,
&sequence_display_backlight_off);
notification_message(state->notification, &sequence_display_backlight_off);
}
}
/* Locks the keyboard. */
static void kbd_lock(ESubGhzChatState *state)
{
static void kbd_lock(ESubGhzChatState* state) {
state->kbd_locked = true;
kbd_lock_msg_reset(state, true);
}
/* Unlocks the keyboard. */
static void kbd_unlock(ESubGhzChatState *state)
{
static void kbd_unlock(ESubGhzChatState* state) {
state->kbd_locked = false;
kbd_lock_msg_reset(state, false);
}
/* Custom event callback for view dispatcher. Just calls scene manager. */
static bool esubghz_chat_custom_event_callback(void* context, uint32_t event)
{
static bool esubghz_chat_custom_event_callback(void* context, uint32_t event) {
FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_custom_event_callback");
furi_assert(context);
ESubGhzChatState* state = context;
@@ -233,8 +211,7 @@ static bool esubghz_chat_custom_event_callback(void* context, uint32_t event)
}
/* Navigation event callback for view dispatcher. Just calls scene manager. */
static bool esubghz_chat_navigation_event_callback(void* context)
{
static bool esubghz_chat_navigation_event_callback(void* context) {
FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_navigation_event_callback");
furi_assert(context);
ESubGhzChatState* state = context;
@@ -244,8 +221,7 @@ static bool esubghz_chat_navigation_event_callback(void* context)
/* Tick event callback for view dispatcher. Called every TICK_INTERVAL. Resets
* the locked message if necessary. Retrieves a received message from the
* Sub-GHz worker and calls post_rx(). Then calls the scene manager. */
static void esubghz_chat_tick_event_callback(void* context)
{
static void esubghz_chat_tick_event_callback(void* context) {
FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_tick_event_callback");
furi_assert(context);
@@ -260,17 +236,14 @@ static void esubghz_chat_tick_event_callback(void* context)
* MESSAGE_COMPLETION_TIMEOUT has expired, retrieve a message and call
* post_rx() */
size_t avail = 0;
while ((avail = subghz_tx_rx_worker_available(state->subghz_worker)) >
0) {
volatile uint32_t since_last_rx = furi_get_tick() -
state->last_time_rx_data;
if (avail < RX_TX_BUFFER_SIZE && since_last_rx <
MESSAGE_COMPLETION_TIMEOUT) {
while((avail = subghz_tx_rx_worker_available(state->subghz_worker)) > 0) {
volatile uint32_t since_last_rx = furi_get_tick() - state->last_time_rx_data;
if(avail < RX_TX_BUFFER_SIZE && since_last_rx < MESSAGE_COMPLETION_TIMEOUT) {
break;
}
size_t rx_size = subghz_tx_rx_worker_read(state->subghz_worker,
state->rx_buffer, RX_TX_BUFFER_SIZE);
size_t rx_size =
subghz_tx_rx_worker_read(state->subghz_worker, state->rx_buffer, RX_TX_BUFFER_SIZE);
post_rx(state, rx_size);
}
@@ -280,8 +253,7 @@ static void esubghz_chat_tick_event_callback(void* context)
/* Hooks into the view port's draw callback to overlay the keyboard locked
* message. */
static void esubghz_hooked_draw_callback(Canvas* canvas, void* context)
{
static void esubghz_hooked_draw_callback(Canvas* canvas, void* context) {
FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_draw_callback");
furi_assert(canvas);
@@ -312,8 +284,7 @@ static void esubghz_hooked_draw_callback(Canvas* canvas, void* context)
/* Hooks into the view port's input callback to handle the user locking the
* keyboard. */
static void esubghz_hooked_input_callback(InputEvent* event, void* context)
{
static void esubghz_hooked_input_callback(InputEvent* event, void* context) {
FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_input_callback");
furi_assert(event);
@@ -330,8 +301,7 @@ static void esubghz_hooked_input_callback(InputEvent* event, void* context)
}
/* back button has been pressed, increase the lock counter */
if (event->key == InputKeyBack && event->type ==
InputTypeShort) {
if(event->key == InputKeyBack && event->type == InputTypeShort) {
state->kbd_lock_count++;
}
@@ -347,8 +317,7 @@ static void esubghz_hooked_input_callback(InputEvent* event, void* context)
if(event->key == InputKeyOk) {
/* if we are in the chat view and no input is ongoing, allow
* locking */
if (state->view_dispatcher->current_view ==
text_box_get_view(state->chat_box) &&
if(state->view_dispatcher->current_view == text_box_get_view(state->chat_box) &&
!(state->kbd_ok_input_ongoing)) {
/* lock keyboard upon long press of Ok button */
if(event->type == InputTypeLong) {
@@ -371,13 +340,12 @@ static void esubghz_hooked_input_callback(InputEvent* event, void* context)
if(event->key == InputKeyLeft) {
/* if we are in the chat view and no input is ongoing, allow
* switching to msg input */
if (state->view_dispatcher->current_view ==
text_box_get_view(state->chat_box) &&
if(state->view_dispatcher->current_view == text_box_get_view(state->chat_box) &&
!(state->kbd_left_input_ongoing)) {
/* go to msg input upon short press of Left button */
if(event->type == InputTypeShort) {
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_GotoMsgInput);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_GotoMsgInput);
}
/* do not handle any Left key events to prevent
@@ -396,14 +364,13 @@ static void esubghz_hooked_input_callback(InputEvent* event, void* context)
if(event->key == InputKeyRight) {
/* if we are in the chat view and no input is ongoing, allow
* switching to key display */
if (state->view_dispatcher->current_view ==
text_box_get_view(state->chat_box) &&
if(state->view_dispatcher->current_view == text_box_get_view(state->chat_box) &&
!(state->kbd_right_input_ongoing)) {
/* go to key display upon short press of Right button
*/
if(event->type == InputTypeShort) {
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_GotoKeyDisplay);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_GotoKeyDisplay);
}
/* do not handle any Right key events to prevent
@@ -423,8 +390,7 @@ static void esubghz_hooked_input_callback(InputEvent* event, void* context)
state->orig_input_cb(event, state->view_dispatcher);
}
static bool helper_strings_alloc(ESubGhzChatState *state)
{
static bool helper_strings_alloc(ESubGhzChatState* state) {
furi_assert(state);
state->name_prefix = furi_string_alloc();
@@ -441,16 +407,14 @@ static bool helper_strings_alloc(ESubGhzChatState *state)
return true;
}
static void helper_strings_free(ESubGhzChatState *state)
{
static void helper_strings_free(ESubGhzChatState* state) {
furi_assert(state);
furi_string_free(state->name_prefix);
furi_string_free(state->msg_input);
}
static bool chat_box_alloc(ESubGhzChatState *state)
{
static bool chat_box_alloc(ESubGhzChatState* state) {
furi_assert(state);
state->chat_box = text_box_alloc();
@@ -466,23 +430,20 @@ static bool chat_box_alloc(ESubGhzChatState *state)
furi_string_reserve(state->chat_box_store, CHAT_BOX_STORE_SIZE);
furi_string_set_char(state->chat_box_store, 0, 0);
text_box_set_text(state->chat_box,
furi_string_get_cstr(state->chat_box_store));
text_box_set_text(state->chat_box, furi_string_get_cstr(state->chat_box_store));
text_box_set_focus(state->chat_box, TextBoxFocusEnd);
return true;
}
static void chat_box_free(ESubGhzChatState *state)
{
static void chat_box_free(ESubGhzChatState* state) {
furi_assert(state);
text_box_free(state->chat_box);
furi_string_free(state->chat_box_store);
}
int32_t esubghz_chat(void)
{
int32_t esubghz_chat(void) {
/* init the crypto system */
crypto_init();
@@ -498,8 +459,7 @@ int32_t esubghz_chat(void)
}
memset(state, 0, sizeof(*state));
state->scene_manager = scene_manager_alloc(
&esubghz_chat_scene_event_handlers, state);
state->scene_manager = scene_manager_alloc(&esubghz_chat_scene_event_handlers, state);
if(state->scene_manager == NULL) {
goto err_alloc_sm;
}
@@ -564,8 +524,7 @@ int32_t esubghz_chat(void)
}
/* set the have_read callback of the Sub-GHz worker */
subghz_tx_rx_worker_set_callback_have_read(state->subghz_worker,
have_read_cb, state);
subghz_tx_rx_worker_set_callback_have_read(state->subghz_worker, have_read_cb, state);
/* enter suppress charge mode */
furi_hal_power_suppress_charge_enter();
@@ -575,8 +534,7 @@ int32_t esubghz_chat(void)
state->subghz_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
/* set chat name prefix */
furi_string_printf(state->name_prefix, "%s",
furi_hal_version_get_name_ptr());
furi_string_printf(state->name_prefix, "%s", furi_hal_version_get_name_ptr());
/* get notification record, we use this to make the flipper vibrate */
/* no error handling here, don't know how */
@@ -585,45 +543,44 @@ int32_t esubghz_chat(void)
/* hook into the view port's draw and input callbacks */
state->orig_draw_cb = state->view_dispatcher->view_port->draw_callback;
state->orig_input_cb = state->view_dispatcher->view_port->input_callback;
view_port_draw_callback_set(state->view_dispatcher->view_port,
esubghz_hooked_draw_callback, state);
view_port_input_callback_set(state->view_dispatcher->view_port,
esubghz_hooked_input_callback, state);
view_port_draw_callback_set(
state->view_dispatcher->view_port, esubghz_hooked_draw_callback, state);
view_port_input_callback_set(
state->view_dispatcher->view_port, esubghz_hooked_input_callback, state);
view_dispatcher_enable_queue(state->view_dispatcher);
/* set callbacks for view dispatcher */
view_dispatcher_set_event_callback_context(state->view_dispatcher, state);
view_dispatcher_set_custom_event_callback(
state->view_dispatcher,
esubghz_chat_custom_event_callback);
state->view_dispatcher, esubghz_chat_custom_event_callback);
view_dispatcher_set_navigation_event_callback(
state->view_dispatcher,
esubghz_chat_navigation_event_callback);
state->view_dispatcher, esubghz_chat_navigation_event_callback);
view_dispatcher_set_tick_event_callback(
state->view_dispatcher,
esubghz_chat_tick_event_callback,
TICK_INTERVAL);
state->view_dispatcher, esubghz_chat_tick_event_callback, TICK_INTERVAL);
/* add our two views to the view dispatcher */
view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_Menu,
menu_get_view(state->menu));
view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_Input,
text_input_get_view(state->text_input));
view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_HexKeyInput,
view_dispatcher_add_view(
state->view_dispatcher, ESubGhzChatView_Menu, menu_get_view(state->menu));
view_dispatcher_add_view(
state->view_dispatcher, ESubGhzChatView_Input, text_input_get_view(state->text_input));
view_dispatcher_add_view(
state->view_dispatcher,
ESubGhzChatView_HexKeyInput,
byte_input_get_view(state->hex_key_input));
view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_ChatBox,
text_box_get_view(state->chat_box));
view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_KeyDisplay,
view_dispatcher_add_view(
state->view_dispatcher, ESubGhzChatView_ChatBox, text_box_get_view(state->chat_box));
view_dispatcher_add_view(
state->view_dispatcher,
ESubGhzChatView_KeyDisplay,
dialog_ex_get_view(state->key_display));
view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_NfcPopup,
popup_get_view(state->nfc_popup));
view_dispatcher_add_view(
state->view_dispatcher, ESubGhzChatView_NfcPopup, popup_get_view(state->nfc_popup));
/* get the GUI record and attach the view dispatcher to the GUI */
/* no error handling here, don't know how */
Gui* gui = furi_record_open(RECORD_GUI);
view_dispatcher_attach_to_gui(state->view_dispatcher, gui,
ViewDispatcherTypeFullscreen);
view_dispatcher_attach_to_gui(state->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
/* switch to the frequency input scene */
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
@@ -647,27 +604,19 @@ int32_t esubghz_chat(void)
furi_record_close(RECORD_GUI);
/* remove our two views from the view dispatcher */
view_dispatcher_remove_view(state->view_dispatcher,
ESubGhzChatView_Menu);
view_dispatcher_remove_view(state->view_dispatcher,
ESubGhzChatView_Input);
view_dispatcher_remove_view(state->view_dispatcher,
ESubGhzChatView_HexKeyInput);
view_dispatcher_remove_view(state->view_dispatcher,
ESubGhzChatView_ChatBox);
view_dispatcher_remove_view(state->view_dispatcher,
ESubGhzChatView_KeyDisplay);
view_dispatcher_remove_view(state->view_dispatcher,
ESubGhzChatView_NfcPopup);
view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_Menu);
view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_Input);
view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_HexKeyInput);
view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_ChatBox);
view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_KeyDisplay);
view_dispatcher_remove_view(state->view_dispatcher, ESubGhzChatView_NfcPopup);
/* close notification record */
furi_record_close(RECORD_NOTIFICATION);
/* clear the key and potential password */
crypto_explicit_bzero(state->text_input_store,
sizeof(state->text_input_store));
crypto_explicit_bzero(state->hex_key_input_store,
sizeof(state->hex_key_input_store));
crypto_explicit_bzero(state->text_input_store, sizeof(state->text_input_store));
crypto_explicit_bzero(state->hex_key_input_store, sizeof(state->hex_key_input_store));
crypto_explicit_bzero(state->key_hex_str, sizeof(state->key_hex_str));
crypto_ctx_clear(state->crypto_ctx);

View File

@@ -1,24 +1,21 @@
#include "../esubghz_chat_i.h"
/* Prepares the text box scene. */
void scene_on_enter_chat_box(void* context)
{
void scene_on_enter_chat_box(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_chat_box");
furi_assert(context);
ESubGhzChatState* state = context;
text_box_reset(state->chat_box);
text_box_set_text(state->chat_box,
furi_string_get_cstr(state->chat_box_store));
text_box_set_text(state->chat_box, furi_string_get_cstr(state->chat_box_store));
text_box_set_focus(state->chat_box, TextBoxFocusEnd);
view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_ChatBox);
}
/* Handles scene manager events for the text box scene. */
bool scene_on_event_chat_box(void* context, SceneManagerEvent event)
{
bool scene_on_event_chat_box(void* context, SceneManagerEvent event) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_event_chat_box");
furi_assert(context);
@@ -31,15 +28,13 @@ bool scene_on_event_chat_box(void* context, SceneManagerEvent event)
switch(event.event) {
/* switch to message input scene */
case ESubGhzChatEvent_GotoMsgInput:
if (!scene_manager_previous_scene(
state->scene_manager)) {
if(!scene_manager_previous_scene(state->scene_manager)) {
view_dispatcher_stop(state->view_dispatcher);
}
consumed = true;
break;
case ESubGhzChatEvent_GotoKeyDisplay:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_KeyDisplay);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyDisplay);
consumed = true;
break;
}
@@ -54,8 +49,7 @@ bool scene_on_event_chat_box(void* context, SceneManagerEvent event)
}
/* Cleans up the text box scene. */
void scene_on_exit_chat_box(void* context)
{
void scene_on_exit_chat_box(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_chat_box");
furi_assert(context);

View File

@@ -6,9 +6,7 @@
* then copied into the TX buffer. The contents of the TX buffer are then
* transmitted. The sent message is appended to the text box and a MsgEntered
* event is sent to the scene manager to switch to the text box view. */
static bool chat_input_validator(const char *text, FuriString *error,
void *context)
{
static bool chat_input_validator(const char* text, FuriString* error, void* context) {
UNUSED(error);
furi_assert(context);
@@ -16,8 +14,7 @@ static bool chat_input_validator(const char *text, FuriString *error,
/* no message, just switch to the text box view */
if(strlen(text) == 0) {
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_MsgEntered);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_MsgEntered);
return true;
}
@@ -36,15 +33,13 @@ static bool chat_input_validator(const char *text, FuriString *error,
furi_string_set_char(state->msg_input, 0, 0);
/* switch to text box view */
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_MsgEntered);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_MsgEntered);
return true;
}
/* Prepares the message input scene. */
void scene_on_enter_chat_input(void* context)
{
void scene_on_enter_chat_input(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_chat_input");
furi_assert(context);
@@ -61,18 +56,14 @@ void scene_on_enter_chat_input(void* context)
state->text_input_store,
sizeof(state->text_input_store),
true);
text_input_set_validator(
state->text_input,
chat_input_validator,
state);
text_input_set_validator(state->text_input, chat_input_validator, state);
set_chat_input_header(state);
view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Input);
}
/* Handles scene manager events for the message input scene. */
bool scene_on_event_chat_input(void* context, SceneManagerEvent event)
{
bool scene_on_event_chat_input(void* context, SceneManagerEvent event) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_event_chat_input");
furi_assert(context);
@@ -85,8 +76,7 @@ bool scene_on_event_chat_input(void* context, SceneManagerEvent event)
switch(event.event) {
/* switch to text box scene */
case ESubGhzChatEvent_MsgEntered:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_ChatBox);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatBox);
consumed = true;
break;
}
@@ -107,8 +97,7 @@ bool scene_on_event_chat_input(void* context, SceneManagerEvent event)
}
/* Cleans up the password input scene. */
void scene_on_exit_chat_input(void* context)
{
void scene_on_exit_chat_input(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_chat_input");
furi_assert(context);

View File

@@ -2,22 +2,17 @@
/* Sends FreqEntered event to scene manager and displays the frequency in the
* text box. */
static void freq_input_cb(void *context)
{
static void freq_input_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
furi_string_cat_printf(state->chat_box_store, "Frequency: %lu",
state->frequency);
furi_string_cat_printf(state->chat_box_store, "Frequency: %lu", state->frequency);
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_FreqEntered);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_FreqEntered);
}
/* Validates the entered frequency. */
static bool freq_input_validator(const char *text, FuriString *error,
void *context)
{
static bool freq_input_validator(const char* text, FuriString* error, void* context) {
furi_assert(text);
furi_assert(error);
@@ -30,10 +25,8 @@ static bool freq_input_validator(const char *text, FuriString *error,
return false;
}
if (!subghz_devices_is_frequency_valid(state->subghz_device,
state->frequency)) {
furi_string_printf(error, "Frequency\n%lu\n is invalid!",
state->frequency);
if(!subghz_devices_is_frequency_valid(state->subghz_device, state->frequency)) {
furi_string_printf(error, "Frequency\n%lu\n is invalid!", state->frequency);
return false;
}
@@ -42,8 +35,7 @@ static bool freq_input_validator(const char *text, FuriString *error,
#else /* FW_ORIGIN_Official */
if(!furi_hal_subghz_is_tx_allowed(state->frequency)) {
#endif /* FW_ORIGIN_Official */
furi_string_printf(error, "TX forbidden\non frequency\n%lu!",
state->frequency);
furi_string_printf(error, "TX forbidden\non frequency\n%lu!", state->frequency);
return false;
}
@@ -51,15 +43,13 @@ static bool freq_input_validator(const char *text, FuriString *error,
}
/* Prepares the frequency input scene. */
void scene_on_enter_freq_input(void* context)
{
void scene_on_enter_freq_input(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_freq_input");
furi_assert(context);
ESubGhzChatState* state = context;
snprintf(state->text_input_store, TEXT_INPUT_STORE_SIZE, "%lu",
(uint32_t) DEFAULT_FREQ);
snprintf(state->text_input_store, TEXT_INPUT_STORE_SIZE, "%lu", (uint32_t)DEFAULT_FREQ);
text_input_reset(state->text_input);
text_input_set_result_callback(
state->text_input,
@@ -68,20 +58,14 @@ void scene_on_enter_freq_input(void* context)
state->text_input_store,
sizeof(state->text_input_store),
true);
text_input_set_validator(
state->text_input,
freq_input_validator,
state);
text_input_set_header_text(
state->text_input,
"Frequency");
text_input_set_validator(state->text_input, freq_input_validator, state);
text_input_set_header_text(state->text_input, "Frequency");
view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Input);
}
/* Handles scene manager events for the frequency input scene. */
bool scene_on_event_freq_input(void* context, SceneManagerEvent event)
{
bool scene_on_event_freq_input(void* context, SceneManagerEvent event) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_event_freq_input");
furi_assert(context);
@@ -94,8 +78,7 @@ bool scene_on_event_freq_input(void* context, SceneManagerEvent event)
switch(event.event) {
/* switch to password input scene */
case ESubGhzChatEvent_FreqEntered:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_KeyMenu);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyMenu);
consumed = true;
break;
}
@@ -116,8 +99,7 @@ bool scene_on_event_freq_input(void* context, SceneManagerEvent event)
}
/* Cleans up the frequency input scene. */
void scene_on_exit_freq_input(void* context)
{
void scene_on_exit_freq_input(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_freq_input");
furi_assert(context);

View File

@@ -2,19 +2,16 @@
/* Sets the entered bytes as the key, enters the chat and sends a HexKeyEntered
* event to the scene manager. */
static void hex_key_input_cb(void* context)
{
static void hex_key_input_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
/* initiate the crypto context */
bool ret = crypto_ctx_set_key(state->crypto_ctx,
state->hex_key_input_store, state->name_prefix,
furi_get_tick());
bool ret = crypto_ctx_set_key(
state->crypto_ctx, state->hex_key_input_store, state->name_prefix, furi_get_tick());
/* cleanup */
crypto_explicit_bzero(state->hex_key_input_store,
sizeof(state->hex_key_input_store));
crypto_explicit_bzero(state->hex_key_input_store, sizeof(state->hex_key_input_store));
if(!ret) {
crypto_ctx_clear(state->crypto_ctx);
@@ -25,32 +22,29 @@ static void hex_key_input_cb(void* context)
enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_HexKeyEntered);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_HexKeyEntered);
}
/* Prepares the hex key input scene. */
void scene_on_enter_hex_key_input(void* context)
{
void scene_on_enter_hex_key_input(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_hex_key_input");
furi_assert(context);
ESubGhzChatState* state = context;
byte_input_set_result_callback(state->hex_key_input,
byte_input_set_result_callback(
state->hex_key_input,
hex_key_input_cb,
NULL,
state,
state->hex_key_input_store,
sizeof(state->hex_key_input_store));
view_dispatcher_switch_to_view(state->view_dispatcher,
ESubGhzChatView_HexKeyInput);
view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_HexKeyInput);
}
/* Handles scene manager events for the hex key input scene. */
bool scene_on_event_hex_key_input(void* context, SceneManagerEvent event)
{
bool scene_on_event_hex_key_input(void* context, SceneManagerEvent event) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_event_hex_key_input");
furi_assert(context);
@@ -63,8 +57,7 @@ bool scene_on_event_hex_key_input(void* context, SceneManagerEvent event)
switch(event.event) {
/* switch to message input scene */
case ESubGhzChatEvent_HexKeyEntered:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_ChatInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
consumed = true;
break;
}
@@ -79,13 +72,11 @@ bool scene_on_event_hex_key_input(void* context, SceneManagerEvent event)
}
/* Cleans up the hex key input scene. */
void scene_on_exit_hex_key_input(void* context)
{
void scene_on_exit_hex_key_input(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_hex_key_input");
furi_assert(context);
ESubGhzChatState* state = context;
crypto_explicit_bzero(state->hex_key_input_store,
sizeof(state->hex_key_input_store));
crypto_explicit_bzero(state->hex_key_input_store, sizeof(state->hex_key_input_store));
}

View File

@@ -1,20 +1,18 @@
#include "../esubghz_chat_i.h"
void key_display_result_cb(DialogExResult result, void* context)
{
void key_display_result_cb(DialogExResult result, void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
switch(result) {
case DialogExResultLeft:
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_KeyDisplayBack);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyDisplayBack);
break;
case DialogExResultCenter:
if(state->encrypted) {
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_KeyDisplayShare);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyDisplayShare);
}
break;
@@ -24,8 +22,7 @@ void key_display_result_cb(DialogExResult result, void* context)
}
/* Prepares the key display scene. */
void scene_on_enter_key_display(void* context)
{
void scene_on_enter_key_display(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_display");
furi_assert(context);
@@ -34,7 +31,9 @@ void scene_on_enter_key_display(void* context)
if(state->encrypted) {
uint8_t key[KEY_BITS / 8];
crypto_ctx_get_key(state->crypto_ctx, key);
snprintf(state->key_hex_str, KEY_HEX_STR_SIZE,
snprintf(
state->key_hex_str,
KEY_HEX_STR_SIZE,
"%02hX%02hX%02hX%02hX"
"%02hX%02hX%02hX%02hX\n"
"%02hX%02hX%02hX%02hX"
@@ -43,14 +42,38 @@ void scene_on_enter_key_display(void* context)
"%02hX%02hX%02hX%02hX\n"
"%02hX%02hX%02hX%02hX"
"%02hX%02hX%02hX%02hX",
key[0], key[1], key[2], key[3],
key[4], key[5], key[6], key[7],
key[8], key[9], key[10], key[11],
key[12], key[13], key[14], key[15],
key[16], key[17], key[18], key[19],
key[20], key[21], key[22], key[23],
key[24], key[25], key[26], key[27],
key[28], key[29], key[30], key[31]);
key[0],
key[1],
key[2],
key[3],
key[4],
key[5],
key[6],
key[7],
key[8],
key[9],
key[10],
key[11],
key[12],
key[13],
key[14],
key[15],
key[16],
key[17],
key[18],
key[19],
key[20],
key[21],
key[22],
key[23],
key[24],
key[25],
key[26],
key[27],
key[28],
key[29],
key[30],
key[31]);
crypto_explicit_bzero(key, sizeof(key));
} else {
strcpy(state->key_hex_str, "No Key");
@@ -58,8 +81,7 @@ void scene_on_enter_key_display(void* context)
dialog_ex_reset(state->key_display);
dialog_ex_set_text(state->key_display, state->key_hex_str, 64, 2,
AlignCenter, AlignTop);
dialog_ex_set_text(state->key_display, state->key_hex_str, 64, 2, AlignCenter, AlignTop);
dialog_ex_set_icon(state->key_display, 0, 0, NULL);
@@ -69,16 +91,14 @@ void scene_on_enter_key_display(void* context)
dialog_ex_set_center_button_text(state->key_display, "Share");
}
dialog_ex_set_result_callback(state->key_display,
key_display_result_cb);
dialog_ex_set_result_callback(state->key_display, key_display_result_cb);
dialog_ex_set_context(state->key_display, state);
view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_KeyDisplay);
}
/* Handles scene manager events for the key display scene. */
bool scene_on_event_key_display(void* context, SceneManagerEvent event)
{
bool scene_on_event_key_display(void* context, SceneManagerEvent event) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_display");
furi_assert(context);
@@ -91,8 +111,7 @@ bool scene_on_event_key_display(void* context, SceneManagerEvent event)
switch(event.event) {
/* switch to message input scene */
case ESubGhzChatEvent_KeyDisplayBack:
if (!scene_manager_previous_scene(
state->scene_manager)) {
if(!scene_manager_previous_scene(state->scene_manager)) {
view_dispatcher_stop(state->view_dispatcher);
}
consumed = true;
@@ -100,8 +119,7 @@ bool scene_on_event_key_display(void* context, SceneManagerEvent event)
/* open key sharing popup */
case ESubGhzChatEvent_KeyDisplayShare:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_KeySharePopup);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeySharePopup);
consumed = true;
break;
}
@@ -116,8 +134,7 @@ bool scene_on_event_key_display(void* context, SceneManagerEvent event)
}
/* Cleans up the key display scene. */
void scene_on_exit_key_display(void* context)
{
void scene_on_exit_key_display(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_display");
furi_assert(context);

View File

@@ -8,8 +8,7 @@ typedef enum {
ESubGhzChatKeyMenuItems_ReadKeyFromNfc,
} ESubGhzChatKeyMenuItems;
static void key_menu_cb(void* context, uint32_t index)
{
static void key_menu_cb(void* context, uint32_t index) {
furi_assert(context);
ESubGhzChatState* state = context;
@@ -20,18 +19,17 @@ static void key_menu_cb(void* context, uint32_t index)
state->encrypted = false;
enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_KeyMenuNoEncryption);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyMenuNoEncryption);
break;
case ESubGhzChatKeyMenuItems_Password:
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_KeyMenuPassword);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyMenuPassword);
break;
case ESubGhzChatKeyMenuItems_HexKey:
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_KeyMenuHexKey);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyMenuHexKey);
break;
case ESubGhzChatKeyMenuItems_GenKey:
@@ -39,8 +37,7 @@ static void key_menu_cb(void* context, uint32_t index)
furi_hal_random_fill_buf(key, KEY_BITS / 8);
/* initiate the crypto context */
bool ret = crypto_ctx_set_key(state->crypto_ctx, key,
state->name_prefix, furi_get_tick());
bool ret = crypto_ctx_set_key(state->crypto_ctx, key, state->name_prefix, furi_get_tick());
/* cleanup */
crypto_explicit_bzero(key, sizeof(key));
@@ -54,13 +51,12 @@ static void key_menu_cb(void* context, uint32_t index)
state->encrypted = true;
enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_KeyMenuGenKey);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyMenuGenKey);
break;
case ESubGhzChatKeyMenuItems_ReadKeyFromNfc:
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_KeyMenuReadKeyFromNfc);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyMenuReadKeyFromNfc);
break;
default:
@@ -69,8 +65,7 @@ static void key_menu_cb(void* context, uint32_t index)
}
/* Prepares the key menu scene. */
void scene_on_enter_key_menu(void* context)
{
void scene_on_enter_key_menu(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_menu");
furi_assert(context);
@@ -84,47 +79,26 @@ void scene_on_enter_key_menu(void* context)
NULL,
ESubGhzChatKeyMenuItems_NoEncryption,
key_menu_cb,
state
);
state);
menu_add_item(
state->menu,
"Password",
NULL,
ESubGhzChatKeyMenuItems_Password,
key_menu_cb,
state
);
state->menu, "Password", NULL, ESubGhzChatKeyMenuItems_Password, key_menu_cb, state);
menu_add_item(
state->menu,
"Hex Key",
NULL,
ESubGhzChatKeyMenuItems_HexKey,
key_menu_cb,
state
);
state->menu, "Hex Key", NULL, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state);
menu_add_item(
state->menu,
"Generate Key",
NULL,
ESubGhzChatKeyMenuItems_GenKey,
key_menu_cb,
state
);
state->menu, "Generate Key", NULL, ESubGhzChatKeyMenuItems_GenKey, key_menu_cb, state);
menu_add_item(
state->menu,
"Read Key from NFC",
NULL,
ESubGhzChatKeyMenuItems_ReadKeyFromNfc,
key_menu_cb,
state
);
state);
view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Menu);
}
/* Handles scene manager events for the key menu scene. */
bool scene_on_event_key_menu(void* context, SceneManagerEvent event)
{
bool scene_on_event_key_menu(void* context, SceneManagerEvent event) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_menu");
furi_assert(context);
@@ -138,29 +112,25 @@ bool scene_on_event_key_menu(void* context, SceneManagerEvent event)
/* switch to message input scene */
case ESubGhzChatEvent_KeyMenuNoEncryption:
case ESubGhzChatEvent_KeyMenuGenKey:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_ChatInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
consumed = true;
break;
/* switch to password input scene */
case ESubGhzChatEvent_KeyMenuPassword:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_PassInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_PassInput);
consumed = true;
break;
/* switch to hex key input scene */
case ESubGhzChatEvent_KeyMenuHexKey:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_HexKeyInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_HexKeyInput);
consumed = true;
break;
/* switch to hex key read scene */
case ESubGhzChatEvent_KeyMenuReadKeyFromNfc:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_KeyReadPopup);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyReadPopup);
consumed = true;
break;
}
@@ -182,8 +152,7 @@ bool scene_on_event_key_menu(void* context, SceneManagerEvent event)
}
/* Cleans up the key menu scene. */
void scene_on_exit_key_menu(void* context)
{
void scene_on_exit_key_menu(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_menu");
furi_assert(context);
@@ -191,4 +160,3 @@ void scene_on_exit_key_menu(void* context)
menu_reset(state->menu);
}

View File

@@ -8,8 +8,7 @@ typedef enum {
KeyReadPopupState_Success,
} KeyReadPopupState;
static bool read_worker_cb(NfcWorkerEvent event, void* context)
{
static bool read_worker_cb(NfcWorkerEvent event, void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
@@ -18,28 +17,26 @@ static bool read_worker_cb(NfcWorkerEvent event, void* context)
return true;
}
static void key_read_popup_timeout_cb(void* context)
{
static void key_read_popup_timeout_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
uint32_t cur_state = scene_manager_get_scene_state(
state->scene_manager, ESubGhzChatScene_KeyReadPopup);
uint32_t cur_state =
scene_manager_get_scene_state(state->scene_manager, ESubGhzChatScene_KeyReadPopup);
/* done displaying our failure */
if(cur_state == KeyReadPopupState_Fail) {
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_KeyReadPopupFailed);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyReadPopupFailed);
/* done displaying our success, enter chat */
} else if(cur_state == KeyReadPopupState_Success) {
enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_KeyReadPopupSucceeded);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyReadPopupSucceeded);
}
}
static bool key_read_popup_handle_key_read(ESubGhzChatState *state)
{
static bool key_read_popup_handle_key_read(ESubGhzChatState* state) {
NfcDeviceData* dev_data = state->nfc_dev_data;
if(dev_data->mf_ul_data.data_read < KEY_BITS / 8) {
@@ -47,9 +44,8 @@ static bool key_read_popup_handle_key_read(ESubGhzChatState *state)
}
/* initiate the crypto context */
bool ret = crypto_ctx_set_key(state->crypto_ctx,
dev_data->mf_ul_data.data, state->name_prefix,
furi_get_tick());
bool ret = crypto_ctx_set_key(
state->crypto_ctx, dev_data->mf_ul_data.data, state->name_prefix, furi_get_tick());
/* cleanup */
crypto_explicit_bzero(dev_data->mf_ul_data.data, KEY_BITS / 8);
@@ -65,11 +61,9 @@ static bool key_read_popup_handle_key_read(ESubGhzChatState *state)
return true;
}
static void key_read_popup_set_state(ESubGhzChatState *state, KeyReadPopupState
new_state)
{
uint32_t cur_state = scene_manager_get_scene_state(
state->scene_manager, ESubGhzChatScene_KeyReadPopup);
static void key_read_popup_set_state(ESubGhzChatState* state, KeyReadPopupState new_state) {
uint32_t cur_state =
scene_manager_get_scene_state(state->scene_manager, ESubGhzChatScene_KeyReadPopup);
if(cur_state == new_state) {
return;
}
@@ -77,66 +71,59 @@ static void key_read_popup_set_state(ESubGhzChatState *state, KeyReadPopupState
if(new_state == KeyReadPopupState_Detecting) {
popup_reset(state->nfc_popup);
popup_disable_timeout(state->nfc_popup);
popup_set_text(state->nfc_popup, "Tap Flipper\n to sender", 97,
24, AlignCenter, AlignTop);
popup_set_text(state->nfc_popup, "Tap Flipper\n to sender", 97, 24, AlignCenter, AlignTop);
popup_set_icon(state->nfc_popup, 0, 8, &I_NFC_manual_60x50);
notification_message(state->notification,
&sequence_blink_start_cyan);
notification_message(state->notification, &sequence_blink_start_cyan);
} else if(new_state == KeyReadPopupState_Reading) {
popup_reset(state->nfc_popup);
popup_disable_timeout(state->nfc_popup);
popup_set_header(state->nfc_popup, "Reading key\nDon't "
"move...", 85, 24, AlignCenter, AlignTop);
popup_set_header(
state->nfc_popup,
"Reading key\nDon't "
"move...",
85,
24,
AlignCenter,
AlignTop);
popup_set_icon(state->nfc_popup, 12, 23, &I_Loading_24);
notification_message(state->notification,
&sequence_blink_start_yellow);
notification_message(state->notification, &sequence_blink_start_yellow);
} else if(new_state == KeyReadPopupState_Fail) {
nfc_worker_stop(state->nfc_worker);
popup_reset(state->nfc_popup);
popup_set_header(state->nfc_popup, "Failure!", 64, 2,
AlignCenter, AlignTop);
popup_set_text(state->nfc_popup, "Failed\nto read\nkey.", 78,
16, AlignLeft, AlignTop);
popup_set_header(state->nfc_popup, "Failure!", 64, 2, AlignCenter, AlignTop);
popup_set_text(state->nfc_popup, "Failed\nto read\nkey.", 78, 16, AlignLeft, AlignTop);
popup_set_icon(state->nfc_popup, 21, 13, &I_Cry_dolph_55x52);
popup_set_timeout(state->nfc_popup, KEY_READ_POPUP_MS);
popup_set_context(state->nfc_popup, state);
popup_set_callback(state->nfc_popup,
key_read_popup_timeout_cb);
popup_set_callback(state->nfc_popup, key_read_popup_timeout_cb);
popup_enable_timeout(state->nfc_popup);
notification_message(state->notification,
&sequence_blink_stop);
notification_message(state->notification, &sequence_blink_stop);
} else if(new_state == KeyReadPopupState_Success) {
nfc_worker_stop(state->nfc_worker);
popup_reset(state->nfc_popup);
popup_set_header(state->nfc_popup, "Key\nread!", 13, 22,
AlignLeft, AlignBottom);
popup_set_header(state->nfc_popup, "Key\nread!", 13, 22, AlignLeft, AlignBottom);
popup_set_icon(state->nfc_popup, 32, 5, &I_DolphinNice_96x59);
popup_set_timeout(state->nfc_popup, KEY_READ_POPUP_MS);
popup_set_context(state->nfc_popup, state);
popup_set_callback(state->nfc_popup,
key_read_popup_timeout_cb);
popup_set_callback(state->nfc_popup, key_read_popup_timeout_cb);
popup_enable_timeout(state->nfc_popup);
notification_message(state->notification, &sequence_success);
notification_message(state->notification,
&sequence_blink_stop);
notification_message(state->notification, &sequence_blink_stop);
}
scene_manager_set_scene_state(state->scene_manager,
ESubGhzChatScene_KeyReadPopup, new_state);
scene_manager_set_scene_state(state->scene_manager, ESubGhzChatScene_KeyReadPopup, new_state);
view_dispatcher_switch_to_view(state->view_dispatcher,
ESubGhzChatView_NfcPopup);
view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_NfcPopup);
}
/* Prepares the key share read scene. */
void scene_on_enter_key_read_popup(void* context)
{
void scene_on_enter_key_read_popup(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_read_popup");
furi_assert(context);
@@ -150,13 +137,12 @@ void scene_on_enter_key_read_popup(void* context)
furi_check(0);
}
nfc_worker_start(state->nfc_worker, NfcWorkerStateRead,
state->nfc_dev_data, read_worker_cb, state);
nfc_worker_start(
state->nfc_worker, NfcWorkerStateRead, state->nfc_dev_data, read_worker_cb, state);
}
/* Handles scene manager events for the key read popup scene. */
bool scene_on_event_key_read_popup(void* context, SceneManagerEvent event)
{
bool scene_on_event_key_read_popup(void* context, SceneManagerEvent event) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_read_popup");
furi_assert(context);
@@ -169,34 +155,29 @@ bool scene_on_event_key_read_popup(void* context, SceneManagerEvent event)
switch(event.event) {
/* card detected */
case NfcWorkerEventCardDetected:
key_read_popup_set_state(state,
KeyReadPopupState_Reading);
key_read_popup_set_state(state, KeyReadPopupState_Reading);
consumed = true;
break;
/* no card detected */
case NfcWorkerEventNoCardDetected:
key_read_popup_set_state(state,
KeyReadPopupState_Detecting);
key_read_popup_set_state(state, KeyReadPopupState_Detecting);
consumed = true;
break;
/* key probably read */
case NfcWorkerEventReadMfUltralight:
if(key_read_popup_handle_key_read(state)) {
key_read_popup_set_state(state,
KeyReadPopupState_Success);
key_read_popup_set_state(state, KeyReadPopupState_Success);
} else {
key_read_popup_set_state(state,
KeyReadPopupState_Fail);
key_read_popup_set_state(state, KeyReadPopupState_Fail);
}
consumed = true;
break;
/* close the popup and go back */
case ESubGhzChatEvent_KeyReadPopupFailed:
if (!scene_manager_previous_scene(
state->scene_manager)) {
if(!scene_manager_previous_scene(state->scene_manager)) {
view_dispatcher_stop(state->view_dispatcher);
}
consumed = true;
@@ -204,15 +185,13 @@ bool scene_on_event_key_read_popup(void* context, SceneManagerEvent event)
/* success, go to chat input */
case ESubGhzChatEvent_KeyReadPopupSucceeded:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_ChatInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
consumed = true;
break;
/* something else happend, treat as failure */
default:
key_read_popup_set_state(state,
KeyReadPopupState_Fail);
key_read_popup_set_state(state, KeyReadPopupState_Fail);
consumed = true;
break;
}
@@ -228,16 +207,15 @@ bool scene_on_event_key_read_popup(void* context, SceneManagerEvent event)
}
/* Cleans up the key read popup scene. */
void scene_on_exit_key_read_popup(void* context)
{
void scene_on_exit_key_read_popup(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_read_popup");
furi_assert(context);
ESubGhzChatState* state = context;
popup_reset(state->nfc_popup);
scene_manager_set_scene_state(state->scene_manager,
ESubGhzChatScene_KeyReadPopup, KeyReadPopupState_Idle);
scene_manager_set_scene_state(
state->scene_manager, ESubGhzChatScene_KeyReadPopup, KeyReadPopupState_Idle);
notification_message(state->notification, &sequence_blink_stop);

View File

@@ -1,7 +1,6 @@
#include "../esubghz_chat_i.h"
static void prepare_nfc_dev_data(ESubGhzChatState *state)
{
static void prepare_nfc_dev_data(ESubGhzChatState* state) {
NfcDeviceData* dev_data = state->nfc_dev_data;
dev_data->protocol = NfcDeviceProtocolMifareUl;
@@ -27,8 +26,7 @@ static void prepare_nfc_dev_data(ESubGhzChatState *state)
}
/* Prepares the key share popup scene. */
void scene_on_enter_key_share_popup(void* context)
{
void scene_on_enter_key_share_popup(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_key_share_popup");
furi_assert(context);
@@ -38,26 +36,21 @@ void scene_on_enter_key_share_popup(void* context)
popup_disable_timeout(state->nfc_popup);
popup_set_header(state->nfc_popup, "Sharing...", 67, 13, AlignLeft,
AlignTop);
popup_set_header(state->nfc_popup, "Sharing...", 67, 13, AlignLeft, AlignTop);
popup_set_icon(state->nfc_popup, 0, 3, &I_NFC_dolphin_emulation_47x61);
popup_set_text(state->nfc_popup, "Sharing\nKey via\nNFC", 90, 28,
AlignCenter, AlignTop);
popup_set_text(state->nfc_popup, "Sharing\nKey via\nNFC", 90, 28, AlignCenter, AlignTop);
prepare_nfc_dev_data(state);
nfc_worker_start(state->nfc_worker, NfcWorkerStateMfUltralightEmulate,
state->nfc_dev_data, NULL, NULL);
nfc_worker_start(
state->nfc_worker, NfcWorkerStateMfUltralightEmulate, state->nfc_dev_data, NULL, NULL);
notification_message(state->notification,
&sequence_blink_start_magenta);
notification_message(state->notification, &sequence_blink_start_magenta);
view_dispatcher_switch_to_view(state->view_dispatcher,
ESubGhzChatView_NfcPopup);
view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_NfcPopup);
}
/* Handles scene manager events for the key share popup scene. */
bool scene_on_event_key_share_popup(void* context, SceneManagerEvent event)
{
bool scene_on_event_key_share_popup(void* context, SceneManagerEvent event) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_event_key_share_popup");
furi_assert(context);
@@ -70,8 +63,7 @@ bool scene_on_event_key_share_popup(void* context, SceneManagerEvent event)
}
/* Cleans up the key share popup scene. */
void scene_on_exit_key_share_popup(void* context)
{
void scene_on_exit_key_share_popup(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_key_share_popup");
furi_assert(context);

View File

@@ -1,26 +1,21 @@
#include "../esubghz_chat_i.h"
/* Sends PassEntered event to scene manager and enters the chat. */
static void pass_input_cb(void *context)
{
static void pass_input_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
crypto_explicit_bzero(state->text_input_store,
sizeof(state->text_input_store));
crypto_explicit_bzero(state->text_input_store, sizeof(state->text_input_store));
enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher,
ESubGhzChatEvent_PassEntered);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_PassEntered);
}
/* If a password was entered this derives a key from the password using a
* single pass of SHA256 and initiates the AES-GCM context for encryption. If
* the initiation fails, the password is rejected. */
static bool pass_input_validator(const char *text, FuriString *error,
void *context)
{
static bool pass_input_validator(const char* text, FuriString* error, void* context) {
furi_assert(text);
furi_assert(error);
@@ -38,8 +33,7 @@ static bool pass_input_validator(const char *text, FuriString *error,
sha256((unsigned char*)text, strlen(text), key);
/* initiate the crypto context */
bool ret = crypto_ctx_set_key(state->crypto_ctx, key,
state->name_prefix, furi_get_tick());
bool ret = crypto_ctx_set_key(state->crypto_ctx, key, state->name_prefix, furi_get_tick());
/* cleanup */
crypto_explicit_bzero(key, sizeof(key));
@@ -56,8 +50,7 @@ static bool pass_input_validator(const char *text, FuriString *error,
}
/* Prepares the password input scene. */
void scene_on_enter_pass_input(void* context)
{
void scene_on_enter_pass_input(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_pass_input");
furi_assert(context);
@@ -72,20 +65,14 @@ void scene_on_enter_pass_input(void* context)
state->text_input_store,
sizeof(state->text_input_store),
true);
text_input_set_validator(
state->text_input,
pass_input_validator,
state);
text_input_set_header_text(
state->text_input,
"Password");
text_input_set_validator(state->text_input, pass_input_validator, state);
text_input_set_header_text(state->text_input, "Password");
view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Input);
}
/* Handles scene manager events for the password input scene. */
bool scene_on_event_pass_input(void* context, SceneManagerEvent event)
{
bool scene_on_event_pass_input(void* context, SceneManagerEvent event) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_event_pass_input");
furi_assert(context);
@@ -98,8 +85,7 @@ bool scene_on_event_pass_input(void* context, SceneManagerEvent event)
switch(event.event) {
/* switch to message input scene */
case ESubGhzChatEvent_PassEntered:
scene_manager_next_scene(state->scene_manager,
ESubGhzChatScene_ChatInput);
scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
consumed = true;
break;
}
@@ -114,14 +100,12 @@ bool scene_on_event_pass_input(void* context, SceneManagerEvent event)
}
/* Cleans up the password input scene. */
void scene_on_exit_pass_input(void* context)
{
void scene_on_exit_pass_input(void* context) {
FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_pass_input");
furi_assert(context);
ESubGhzChatState* state = context;
text_input_reset(state->text_input);
crypto_explicit_bzero(state->text_input_store,
sizeof(state->text_input_store));
crypto_explicit_bzero(state->text_input_store, sizeof(state->text_input_store));
}

View File

@@ -9,16 +9,13 @@
#include "wire_tester_icons.h"
//#define TAG "wire_tester"
static const uint32_t EVENT_PERIOD_MS = 10; // check for input changes often
static const float BEEP_FREQ = 2400.0f; // louder than other frequencies
static const float BEEP_VOL = 0.8f;
static const GpioPin* const INPUT_PIN = &gpio_ext_pb2; // pin 6
static void start_feedback(NotificationApp* notifications) {
// set LED to green
notification_message_block(notifications, &sequence_set_only_green_255);
@@ -88,8 +85,8 @@ int32_t app_main(void* p) {
// exit on back key
InputEvent event;
if(furi_message_queue_get(event_queue, &event, EVENT_PERIOD_MS) == FuriStatusOk) {
if ((event.type == InputTypePress || event.type == InputTypeRepeat)
&& event.key == InputKeyBack) {
if((event.type == InputTypePress || event.type == InputTypeRepeat) &&
event.key == InputKeyBack) {
running = false;
}
}