@@ -9,6 +9,7 @@ fs::SPIFFSFS &FlashFS = SPIFFS;
9
9
#include < stdio.h>
10
10
#include " qrcoded.h"
11
11
#include < WiFiClientSecure.h>
12
+ #include " mbedtls/aes.h"
12
13
13
14
// ArduinoJson, Keypad and uBitcoin should be installed using the Arduino Library Manager.
14
15
// The latest versions should work, verified with ArduinoJson 7.2.1, Keypad 3.1.1 and uBitcoin 0.2.0
@@ -23,7 +24,6 @@ fs::SPIFFSFS &FlashFS = SPIFFS;
23
24
#define USB_POWER 1000 // battery percentage sentinel value to indicate USB power
24
25
25
26
// ////////SET TO TRUE TO WIPE MEMORY//////////////
26
-
27
27
bool format = false ;
28
28
29
29
// //////////////////////////////////////////////////////
@@ -80,7 +80,7 @@ const char currencyItems[3][5] = {"sat", "USD", "EUR"};
80
80
char decimalplacesOutput[20 ];
81
81
int menuItemCheck[5 ] = {0 , 0 , 0 , 0 , 1 };
82
82
int menuItemNo = 0 ;
83
- int randomPin;
83
+ String randomPin;
84
84
int calNum = 1 ;
85
85
int sumFlag = 0 ;
86
86
int converted = 0 ;
@@ -931,9 +931,9 @@ void qrShowCodeln()
931
931
qrData.toUpperCase ();
932
932
const char *qrDataChar = qrData.c_str ();
933
933
QRCode qrcoded;
934
- uint8_t qrcodeData[qrcode_getBufferSize (20 )];
934
+ uint8_t qrcodeData[qrcode_getBufferSize (32 )];
935
935
936
- qrcode_initText (&qrcoded, qrcodeData, 11 , 0 , qrDataChar);
936
+ qrcode_initText (&qrcoded, qrcodeData, 32 , 0 , qrDataChar);
937
937
938
938
for (uint8_t y = 0 ; y < qrcoded.size ; y++)
939
939
{
@@ -1011,20 +1011,24 @@ void qrShowCodeLNURL(String message)
1011
1011
qrData.toUpperCase ();
1012
1012
const char *qrDataChar = qrData.c_str ();
1013
1013
QRCode qrcoded;
1014
- uint8_t qrcodeData[qrcode_getBufferSize (20 )];
1015
- qrcode_initText (&qrcoded, qrcodeData, 6 , 0 , qrDataChar);
1014
+ uint8_t qrcodeData[qrcode_getBufferSize (11 )];
1015
+ qrcode_initText (&qrcoded, qrcodeData, 11 , 0 , qrDataChar);
1016
+
1017
+ unsigned int pixSize = 2 ;
1018
+ unsigned int offsetTop = 3 ;
1019
+ unsigned int offsetLeft = 65 ;
1016
1020
1017
1021
for (uint8_t y = 0 ; y < qrcoded.size ; y++)
1018
1022
{
1019
1023
for (uint8_t x = 0 ; x < qrcoded.size ; x++)
1020
1024
{
1021
1025
if (qrcode_getModule (&qrcoded, x, y))
1022
1026
{
1023
- tft.fillRect (65 + 3 * x, 5 + 3 * y, 3 , 3 , TFT_BLACK);
1027
+ tft.fillRect (offsetLeft + pixSize * x, offsetTop + pixSize * y, pixSize, pixSize , TFT_BLACK);
1024
1028
}
1025
1029
else
1026
1030
{
1027
- tft.fillRect (65 + 3 * x, 5 + 3 * y, 3 , 3 , qrScreenBgColour);
1031
+ tft.fillRect (offsetLeft + pixSize * x, offsetTop + pixSize * y, pixSize, pixSize , qrScreenBgColour);
1028
1032
}
1029
1033
}
1030
1034
}
@@ -1579,43 +1583,68 @@ void to_upper(char *arr)
1579
1583
1580
1584
bool makeLNURL ()
1581
1585
{
1582
- if (amountToShow.toFloat () = = 0 )
1586
+ if (amountToShow.toFloat () < = 0 )
1583
1587
{
1584
- error (" ZERO VALUE " );
1588
+ error (" ZERO AMOUNT " );
1585
1589
delay (3000 );
1586
1590
return false ;
1587
1591
}
1588
1592
1589
- randomPin = random (1000 , 9999 );
1590
- byte nonce[8 ];
1591
- for (int i = 0 ; i < 8 ; i++)
1592
- {
1593
- nonce[i] = random (256 );
1594
- }
1595
-
1596
1593
int multipler = pow (10 , 2 );
1597
-
1598
1594
if (currencyPoS == " sat" )
1599
1595
{
1600
1596
multipler = 1 ;
1601
1597
}
1602
1598
1603
1599
float total = amountToShow.toFloat () * multipler;
1604
1600
1605
- byte payload[51 ]; // 51 bytes is max one can get with xor-encryption
1601
+ // const char* key = "Yq3t6w9z$C&F)J@M";
1602
+
1603
+ unsigned char iv_init[16 ];
1604
+ unsigned char iv[16 ];
1605
+
1606
+ for (int i = 0 ; i < 16 ; i++) {
1607
+ iv[i] = random (0 , 255 );
1608
+ iv_init[i] = iv[i];
1609
+ }
1610
+
1606
1611
if (selection == " Offline PoS" )
1607
1612
{
1608
- size_t payload_len = xor_encrypt (payload, sizeof (payload), (uint8_t *)secretPoS.c_str (), secretPoS.length (), nonce, sizeof (nonce), randomPin, total);
1609
- preparedURL = baseURLPoS + " ?p=" ;
1610
- preparedURL += toBase64 (payload, payload_len, BASE64_URLSAFE | BASE64_NOPADDING);
1613
+ randomPin = String (random (1000 , 9999 ));
1614
+ preparedURL = baseURLATM;
1611
1615
}
1612
1616
else // ATM
1613
1617
{
1614
- size_t payload_len = xor_encrypt (payload, sizeof (payload), (uint8_t *)secretATM.c_str (), secretATM.length (), nonce, sizeof (nonce), randomPin, total);
1615
- preparedURL = baseURLATM + " ?atm=1&p=" ;
1616
- preparedURL += toBase64 (payload, payload_len, BASE64_URLSAFE | BASE64_NOPADDING);
1618
+ randomPin = String (" FFFF" );
1619
+ preparedURL = baseURLATM + " /atm/" ;
1620
+ }
1621
+ preparedURL += " ?p=" ;
1622
+
1623
+ String payload = randomPin + String (" :" ) + String (total);
1624
+ Serial.print (" payload: " );
1625
+ Serial.println (payload);
1626
+ size_t payload_len = payload.length ();
1627
+ int padding = 16 - (payload_len % 16 );
1628
+ unsigned char encrypted[payload_len + padding] = {0 };
1629
+ String s = " " ;
1630
+ encrypt (secretATM.c_str (), iv, payload_len + padding, payload.c_str (), encrypted);
1631
+ for (int i = 0 ; i < sizeof (encrypted); i++) {
1632
+ s = String (encrypted[i], HEX);
1633
+ if (s.length () == 1 ) {
1634
+ s = " 0" + s;
1635
+ }
1636
+ preparedURL += s;
1637
+ }
1638
+ // append iv to the url
1639
+ preparedURL += " &iv=" ;
1640
+ for (int i = 0 ; i < sizeof (iv_init); i++) {
1641
+ s = String (iv_init[i], HEX);
1642
+ if (s.length () == 1 ) {
1643
+ s = " 0" + s;
1644
+ }
1645
+ preparedURL += s;
1617
1646
}
1618
-
1647
+ Serial. println ();
1619
1648
Serial.println (preparedURL);
1620
1649
char Buf[200 ];
1621
1650
preparedURL.toCharArray (Buf, 200 );
@@ -1632,58 +1661,6 @@ bool makeLNURL()
1632
1661
return true ;
1633
1662
}
1634
1663
1635
- int xor_encrypt (uint8_t *output, size_t outlen, uint8_t *key, size_t keylen, uint8_t *nonce, size_t nonce_len, uint64_t pin, uint64_t amount_in_cents)
1636
- {
1637
- // check we have space for all the data:
1638
- // <variant_byte><len|nonce><len|payload:{pin}{amount}><hmac>
1639
- if (outlen < 2 + nonce_len + 1 + lenVarInt (pin) + 1 + lenVarInt (amount_in_cents) + 8 )
1640
- {
1641
- return 0 ;
1642
- }
1643
-
1644
- int cur = 0 ;
1645
- output[cur] = 1 ; // variant: XOR encryption
1646
- cur++;
1647
-
1648
- // nonce_len | nonce
1649
- output[cur] = nonce_len;
1650
- cur++;
1651
- memcpy (output + cur, nonce, nonce_len);
1652
- cur += nonce_len;
1653
-
1654
- // payload, unxored first - <pin><currency byte><amount>
1655
- int payload_len = lenVarInt (pin) + 1 + lenVarInt (amount_in_cents);
1656
- output[cur] = (uint8_t )payload_len;
1657
- cur++;
1658
- uint8_t *payload = output + cur; // pointer to the start of the payload
1659
- cur += writeVarInt (pin, output + cur, outlen - cur); // pin code
1660
- cur += writeVarInt (amount_in_cents, output + cur, outlen - cur); // amount
1661
- cur++;
1662
-
1663
- // xor it with round key
1664
- uint8_t hmacresult[32 ];
1665
- SHA256 h;
1666
- h.beginHMAC (key, keylen);
1667
- h.write ((uint8_t *)" Round secret:" , 13 );
1668
- h.write (nonce, nonce_len);
1669
- h.endHMAC (hmacresult);
1670
- for (int i = 0 ; i < payload_len; i++)
1671
- {
1672
- payload[i] = payload[i] ^ hmacresult[i];
1673
- }
1674
-
1675
- // add hmac to authenticate
1676
- h.beginHMAC (key, keylen);
1677
- h.write ((uint8_t *)" Data:" , 5 );
1678
- h.write (output, cur);
1679
- h.endHMAC (hmacresult);
1680
- memcpy (output + cur, hmacresult, 8 );
1681
- cur += 8 ;
1682
-
1683
- // return number of bytes written to the output
1684
- return cur;
1685
- }
1686
-
1687
1664
unsigned int getBatteryPercentage ()
1688
1665
{
1689
1666
const float batteryMaxVoltage = 4.2 ;
@@ -1900,3 +1877,12 @@ void printSleepAnimationFrame(String text, int wait)
1900
1877
tft.println (text);
1901
1878
delay (wait );
1902
1879
}
1880
+
1881
+ // ////////ENCRYPTION///////////////
1882
+ void encrypt (const char * key, unsigned char * iv, int length, const char * plainText, unsigned char * outputBuffer){
1883
+ mbedtls_aes_context aes;
1884
+ mbedtls_aes_init (&aes);
1885
+ mbedtls_aes_setkey_enc (&aes, (const unsigned char *)key, strlen (key)*8 );
1886
+ mbedtls_aes_crypt_cbc (&aes, MBEDTLS_AES_ENCRYPT, length, iv, (const unsigned char *)plainText, outputBuffer);
1887
+ mbedtls_aes_free (&aes);
1888
+ }
0 commit comments