Absolutely! I really like them, but they are definitely one of the most care-intensive bodymods… You’ll basically have to take care of them for as long as you have them.
I read this out of context and thought you were referring to the FlexNExT I just scrolled up and realized you were referring to transdermals.
Hehe, nah - guess that little guy will be all nice soon and stay like that forever
Since not everybody has a Proxmark3, here’s a version of the script that uses an ACR122U reader instead. The performance is similarly craptastic, but at least it work. really good! It goes up to 135 WPM on an ordinary PC [EDIT: I thought it was crap because I coded it in a virtual machine, and it won’t go over 10 WPM without timing overruns in that kind of environment]
Tested on Linux running PCSC-Lite. It ought to work in Windows with very minor modifications, but I haven’t tried.
#!/usr/bin/python3
### Parameters
default_wpm = 10 #words per minute
msg_start_pause = " "
msg_end_pause = " "
### Modules
import sys
import argparse
from time import sleep
from datetime import datetime
from smartcard.scard import *
### Defines
# Morse code dictionary
morsecode = {
"A": ".-",
"B": "-...",
"C": "-.-.",
"D": "-..",
"E": ".",
"F": "..-.",
"G": "--.",
"H": "....",
"I": "..",
"J": ".---",
"K": "-.-",
"L": ".-..",
"M": "--",
"N": "-.",
"O": "---",
"P": ".--.",
"Q": "--.-",
"R": ".-.",
"S": "...",
"T": "-",
"U": "..-",
"V": "...-",
"W": ".--",
"X": "-..-",
"Y": "-.--",
"Z": "--..",
"1": ".----",
"2": "..---",
"3": "...--",
"4": "....-",
"5": ".....",
"6": "-....",
"7": "--...",
"8": "---..",
"9": "----.",
"0": "-----",
"=": "-...-",
"/": "-..-.",
"?": "..--..",
",": "--..--",
".": ".-.-.-",
":": "---...",
"'": ".----.",
'"': ".-..-.",
"_": "..--.-",
"(": "-.--.",
")": "-.--.-",
"#": "-.---",
"-": "-....-",
"|": "...-..",
"\\": "-.....",
"*": "-----.",
";": "-.-.-.",
"@": ".--.-.",
"^": "....--.-.",
"$": "...-..-",
"!": "....-.",
">": "....---.",
"]": "....-....",
"[": "....-..",
"<": "....-.-..",
"&": "....--.",
"%": "....-.--.",
"~": "....--",
"+": ".-.-.",
"{": "....-.--",
"}": "....--..-",
"[AR]": ".-.-.",
"[AS]": ".-...",
"[BK]": "-...-.-",
"[BT]": "-...-",
"[KA]": "-.-.-",
"[CL]": "-.-..-..",
"[KN]": "-.--.",
"[VA]": "...-.-",
"[VE]": "...-.",
"[GR]": "--..-.",
"[HM]": "....--",
"[IX]": "..-..-",
"[IMI]": "..--..",
"[INT]": "..-.-",
"[SOS]": "...---..."}
# CCID escape command
ioctl_ccid_escape = SCARD_CTL_CODE(1) # For PCSC-Lite. Use 3500 for Windows
# ACR122U pseudo-APDU commands
cmd_get_fw_revision = [0xff, 0x00, 0x48, 0x00, 0x00]
cmd_disable_polling = [0xff, 0x00, 0x51, 0x00, 0x00]
cmd_enable_polling = [0xff, 0x00, 0x51, 0xff, 0x00]
# PN53x commands, wrapped in ACR122U direct transmit pseudo-APDUs
cmd_rf_field_off = [0xff, 0x00, 0x00, 0x00, 0x04, 0xd4, 0x32, 0x01, 0x00]
cmd_rf_field_on = [0xff, 0x00, 0x00, 0x00, 0x04, 0xd4, 0x32, 0x01, 0x01]
### Routines
def send_acr122u_control_command(cmd, hcard):
"""Send the ACR122U a control command, return the raw result and raise an
exception in case of error
"""
hresult, response = SCardControl(hcard, ioctl_ccid_escape, cmd)
if hresult != SCARD_S_SUCCESS:
raise SystemError("Failure to control: {}".format(
SCardGetErrorMessage(hresult)))
return(response)
### Main routine
def main():
"""Main routine
"""
# Read the command line arguments
argparser = argparse.ArgumentParser()
argparser.add_argument(
"-w", "--words-per-minute",
type = int,
help = "Rate of the morse code (default: {})".format(default_wpm),
default = default_wpm,
required = False
)
argparser.add_argument(
"message",
type = str,
help = "Text to output in morse code on LED implant",
)
args = argparser.parse_args()
wpm = args.words_per_minute
msg = args.message.upper()
if not msg:
print("Nothing to do")
return(0)
# Add a pause at the beginning and at the end of the message
msg = msg_start_pause + msg + msg_end_pause
# Turn the message into a sequence of field-on durations (positive) and
# field-off durations (negative)
morsechars = []
i = 0
while i < len(msg):
if msg[i] == "[":
j = msg.find("]", i + 1)
if j > 0 and msg[i : j + 1] in morsecode:
morsechars.append(morsecode[msg[i : j + 1]])
i = j + 1
continue
if msg[i] == " " or msg[i] == "\t":
morsechars.append(" ")
elif msg[i] in morsecode:
morsechars.append(morsecode[msg[i]])
else:
print("Untranslatable in morse code: {} - dropped".format(msg[i]))
i += 1
ditlen = 1.2 / wpm
morseseq = []
for mc in morsechars:
if mc == " ":
if morseseq:
morseseq[-1] = -ditlen * 7
else:
morseseq.append(-ditlen * 7)
continue
for c in mc:
if c == ".":
morseseq.append(ditlen)
else:
morseseq.append(ditlen * 3)
morseseq.append(-ditlen)
morseseq[-1] = -ditlen * 3
# Establish context and connect to the reader
try:
hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
hresult, hcard, dwActiveProtocol = SCardConnect(hcontext,
'ACS ACR122U PICC Interface 00 00',
SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0)
except:
print("Cannot connect to ACR122U")
return(-1)
# Get the ACR122U's firmware revision number, to test that CCID escape has
# been enabled and to double-check that the reader is indeed an ACR122U
try:
fwrev = "".join([chr(v) for v in send_acr122u_control_command(
cmd_get_fw_revision, hcard)])
except:
print("Error getting ACR122U firmware revision number.")
print("Is the CCID exchange command allowed in /etc/libccid_Info.plist")
return(-2)
if fwrev[:7].upper() != "ACR122U":
print('Error: "{}" does not appear to be an ACR122U'.format(fwrev))
return(-3)
# Disable polling so the reader won't try to read the implant when the field
# is turned on
try:
send_acr122u_control_command(cmd_disable_polling, hcard)
except:
print("Error disabling polling")
return(-4)
# Play the morse code sequence
warn_if_too_fast = True
for d in morseseq:
# Flip the RF field on or off
cmd_start_tstamp = datetime.now().timestamp()
try:
send_acr122u_control_command(cmd_rf_field_off if d < 0 \
else cmd_rf_field_on, hcard)
except:
print("Error switching the RF field {}".format("off" if d < 0 else "on"))
return(-5)
cmd_duration = datetime.now().timestamp() - cmd_start_tstamp
# Wait for however long it takes to match the duration in the sequence
remaining_wait = abs(d) - cmd_duration
if remaining_wait > 0:
sleep(remaining_wait)
else:
if warn_if_too_fast:
print("Warning: {} WPM is too fast for the ACR122U and/or your " \
"computer.".format(wpm))
print("Morse code timing may appear incorrect")
warn_if_too_fast = False
# Re-enable the RF field and re-enable polling so the reader can work again
# as a regular reader
try:
send_acr122u_control_command(cmd_rf_field_on, hcard)
except:
print("Error re-enabling the RF field")
return(-5)
try:
send_acr122u_control_command(cmd_enable_polling, hcard)
except:
print("Error re-enabling polling")
return(-6)
### Jump to the main routine
if __name__ == "__main__":
sys.exit(main())
Here’s yet another version of the script: this one can talk to an ACR122U through the PS/SC, or directly to any PN53x reader through USB (including an ACR122U):
#!/usr/bin/python3
"""Small program to flash a morse code message on an NFC LED implant using
either a ACR122U reader through PC/SC, or a PN53x-based USB reader directly
(including a ACR122U)
The pyscard module is required for operation with PC/SC
The nfcpy module is required for direct USB operation with a PN53x-based reader
"""
### Parameters
default_interface = "pn53x_usb"
default_wpm = 10 #words per minute
msg_start_pause = " "
msg_end_pause = " "
### Modules
import sys
import argparse
from time import sleep
from datetime import datetime
### Defines
# Morse code dictionary
morsecode = {
"A": ".-",
"B": "-...",
"C": "-.-.",
"D": "-..",
"E": ".",
"F": "..-.",
"G": "--.",
"H": "....",
"I": "..",
"J": ".---",
"K": "-.-",
"L": ".-..",
"M": "--",
"N": "-.",
"O": "---",
"P": ".--.",
"Q": "--.-",
"R": ".-.",
"S": "...",
"T": "-",
"U": "..-",
"V": "...-",
"W": ".--",
"X": "-..-",
"Y": "-.--",
"Z": "--..",
"1": ".----",
"2": "..---",
"3": "...--",
"4": "....-",
"5": ".....",
"6": "-....",
"7": "--...",
"8": "---..",
"9": "----.",
"0": "-----",
"=": "-...-",
"/": "-..-.",
"?": "..--..",
",": "--..--",
".": ".-.-.-",
":": "---...",
"'": ".----.",
'"': ".-..-.",
"_": "..--.-",
"(": "-.--.",
")": "-.--.-",
"#": "-.---",
"-": "-....-",
"|": "...-..",
"\\": "-.....",
"*": "-----.",
";": "-.-.-.",
"@": ".--.-.",
"^": "....--.-.",
"$": "...-..-",
"!": "....-.",
">": "....---.",
"]": "....-....",
"[": "....-..",
"<": "....-.-..",
"&": "....--.",
"%": "....-.--.",
"~": "....--",
"+": ".-.-.",
"{": "....-.--",
"}": "....--..-",
"[AR]": ".-.-.",
"[AS]": ".-...",
"[BK]": "-...-.-",
"[BT]": "-...-",
"[KA]": "-.-.-",
"[CL]": "-.-..-..",
"[KN]": "-.--.",
"[VA]": "...-.-",
"[VE]": "...-.",
"[GR]": "--..-.",
"[HM]": "....--",
"[IX]": "..-..-",
"[IMI]": "..--..",
"[INT]": "..-.-",
"[SOS]": "...---..."}
# CCID escape command
ioctl_ccid_escape_code = 1 # 1 for PCSC-Lite, 3500 for Windows
# ACR122U pseudo-APDU commands
cmd_get_fw_revision = [0xff, 0x00, 0x48, 0x00, 0x00]
cmd_disable_polling = [0xff, 0x00, 0x51, 0x00, 0x00]
cmd_enable_polling = [0xff, 0x00, 0x51, 0xff, 0x00]
# PN53x commands, wrapped in ACR122U direct transmit pseudo-APDUs
cmd_rf_field_off = [0xff, 0x00, 0x00, 0x00, 0x04, 0xd4, 0x32, 0x01, 0x00]
cmd_rf_field_on = [0xff, 0x00, 0x00, 0x00, 0x04, 0xd4, 0x32, 0x01, 0x01]
### Routines
def send_acr122u_control_command(cmd, hcard):
"""Send the ACR122U a control command, return the raw result and raise an
exception in case of error
"""
hresult, response = SCardControl(hcard, ioctl_ccid_escape, cmd)
if hresult != SCARD_S_SUCCESS:
raise SystemError("Failure to control: {}".format(
SCardGetErrorMessage(hresult)))
return(response)
def nfc_morse_player(do_pcsc, wpm, msg):
"""Morse code player
"""
if not msg:
print("Nothing to do!")
return(0)
# Add a pause at the beginning and at the end of the message
msg = msg_start_pause + msg + msg_end_pause
# Turn the message into a sequence of field-on durations (positive) and
# field-off durations (negative)
msg = msg.upper()
morsechars = []
i = 0
while i < len(msg):
if msg[i] == "[":
j = msg.find("]", i + 1)
if j > 0 and msg[i : j + 1] in morsecode:
morsechars.append(morsecode[msg[i : j + 1]])
i = j + 1
continue
if msg[i] == " " or msg[i] == "\t":
morsechars.append(" ")
elif msg[i] in morsecode:
morsechars.append(morsecode[msg[i]])
else:
print("Untranslatable in morse code: {} - dropped".format(msg[i]))
i += 1
ditlen = 1.2 / wpm
morseseq = []
for mc in morsechars:
if mc == " ":
if morseseq:
morseseq[-1] = -ditlen * 7
else:
morseseq.append(-ditlen * 7)
continue
for c in mc:
if c == ".":
morseseq.append(ditlen)
else:
morseseq.append(ditlen * 3)
morseseq.append(-ditlen)
morseseq[-1] = -ditlen * 3
# Set things up using the PC/SC interface
if do_pcsc:
# Establish context and connect to the reader
try:
hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
hresult, hcard, dwActiveProtocol = SCardConnect(hcontext,
'ACS ACR122U PICC Interface 00 00',
SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0)
except:
print("Cannot connect to ACR122U")
return(-1)
# Get the ACR122U's firmware revision number, to test that CCID escape has
# been enabled and to double-check that the reader is indeed an ACR122U
try:
fwrev = "".join([chr(v) for v in send_acr122u_control_command(
cmd_get_fw_revision, hcard)])
except:
print("Error getting ACR122U firmware revision number.")
print("Is the CCID exchange command allowed in /etc/libccid_Info.plist")
return(-2)
if fwrev[:7].upper() != "ACR122U":
print('Error: "{}" does not appear to be an ACR122U'.format(fwrev))
return(-3)
# Disable polling so the reader won't try to read the implant when the field
# is turned on
try:
send_acr122u_control_command(cmd_disable_polling, hcard)
except:
print("Error disabling polling")
return(-4)
# Set things up using the direct PN53x USB interface
else:
# Open the PN53x USB reader
try:
clf = ContactlessFrontend()
if not clf.open("usb"):
raise SystemError
except:
print("Error opening the PN53x USB reader")
return(-1)
# Play the morse code sequence
warn_if_too_fast = True
for d in morseseq:
# Flip the RF field on or off
cmd_start_tstamp = datetime.now().timestamp()
try:
if do_pcsc: # Use the PC/SC interface
send_acr122u_control_command(cmd_rf_field_off if d < 0 \
else cmd_rf_field_on, hcard)
else: # Use the direct PN53x USb interface
clf.device.chipset.rf_configuration(0x01, b"\00" if d < 0 else b"\01")
except:
print("Error switching the RF field {}".format("off" if d < 0 else "on"))
return(-5)
cmd_duration = datetime.now().timestamp() - cmd_start_tstamp
# Wait for however long it takes to match the duration in the sequence
remaining_wait = abs(d) - cmd_duration
if remaining_wait > 0:
sleep(remaining_wait)
else:
if warn_if_too_fast:
print("Warning: {} WPM is too fast for the ACR122U and/or your " \
"computer.".format(wpm))
print("Morse code timing may appear incorrect")
warn_if_too_fast = False
# Clean things up using the PC/SC interface
if do_pcsc:
# Re-enable the RF field and re-enable polling so the reader can work again
# as a regular reader
try:
send_acr122u_control_command(cmd_rf_field_on, hcard)
except:
print("Error re-enabling the RF field")
return(-5)
try:
send_acr122u_control_command(cmd_enable_polling, hcard)
except:
print("Error re-enabling polling")
return(-6)
# Clean things up using the direct PN53x USb interface
else:
clf.close()
### Main routine
if __name__ == "__main__":
# Read the command line arguments
argparser = argparse.ArgumentParser()
argparser.add_argument(
"-i", "--interface",
type = str,
help = "Reader interface (default: {})".format(default_interface),
choices = ("pcsc", "pn53x_usb"),
default = default_interface,
required = False
)
argparser.add_argument(
"-w", "--words-per-minute",
type = int,
help = "Rate of the morse code (default: {})".format(default_wpm),
default = default_wpm,
required = False
)
argparser.add_argument(
"message",
type = str,
help = "Text to output in morse code on LED implant",
)
args = argparser.parse_args()
do_pcsc = args.interface == "pcsc"
# Conditionally import the relevant module here, so the user doesn't have to
# install the other if they don't plan on using that particular interface
if do_pcsc:
from smartcard.scard import * # From the pyscard package
# We can only set this variable here
ioctl_ccid_escape = SCARD_CTL_CODE(ioctl_ccid_escape_code)
else:
from nfc import * # From the nfcpy package
sys.exit(nfc_morse_player(do_pcsc, args.words_per_minute, args.message))
Essentially, any USB PN53x reader that works with libnfc will work with the direct USB mode. The reason I added it is because I wanted to use my DL533N-XL long-range reader to drive my doNExT’s LEDs, and the DL533N-XL isn’t supported by PCSC-Lite.
And look how gloriously it works: my arm is about half an inch off the reader and it lights up like a Christmas tree!
Maybe it’s time you get a repo for this?
Whatever I watch on dailymotion, the next video is always a trailer of:
Yes, Dailymotion sucks major ass. I hate it with a passion (and Vimeo sucks even harder). But it has one advantage: it’s not Youtube / Google. At least not completely.
I thought of compressing the video to under 8 gigs and uploading it here directly, but then I’d be wasting Amal’s bandwidth.
As for a repo for the code, those are transitional trial-and-error code snippets, to try and figure out on which hardware I’ll base my smart NFC bracelet thingy. I really can’t be bothered to upload it on Github.
I love the idea:
In a Dystopian future, a small group of individuals rebel against the man.
Trading secrets and information in plain sight,
small “info stations” are set up around the city, they could look like power boxes on electric poles, mail boxes, The button box for the stop lights at the pedestrian crossing.
But when the bio hackers rest their arm on the station, they get the Morse code information within seconds.
Info can consist of:
Place/date of next rebel meeting
what streets the drone militia is roaming that day
a request for someone to come help fix a computer (XD)
Anyway, back on topic.
This concept is really cool, i love giving the blinkies even more application
Actually I’m thinking of another application for the blinkies - a security applicaton. Imagine this:
There’s a camera in a fixed position on top of the reader. When I present my arm, the computer sees the blinkies light up, recognizes the triangular shape and orientation on my arm, flashes them quickly a few times in a random pattern to check if the feedback from the camera matches, and only then triggers a read and checks the password on the NTAG.
It’s still not proper crypto security, but I reckon it would make it really quite hard to impersonate me.
Thats really smart
I didn’t know Adrien Brody had placed such a big order of FlexNExTs
It was a promo deal hahah