def HMACSha256(keyBin, msgBin): from uhashlib import sha256 block_size = 64 # SHA-256 blocks size trans_5C = bytearray(256) for x in range(len(trans_5C)): trans_5C[x] = x ^ 0x5C trans_36 = bytearray(256) for x in range(len(trans_36)): trans_36[x] = x ^ 0x36 def translate(d, t): res = bytearray(len(d)) for x in range(len(d)): res[x] = t[d[x]] return res keyBin = keyBin + chr(0) * (block_size - len(keyBin)) inner = sha256() inner.update(translate(keyBin, trans_36)) inner.update(msgBin) inner = inner.digest() outer = sha256() outer.update(translate(keyBin, trans_5C)) outer.update(inner) return outer.digest()
def hmac_sha256(key_K, data): if len(key_K) > 64: raise ValueError('The key must be <= 64 bytes in length') padded_K = key_K + b'\x00' * (64 - len(key_K)) ipad = b'\x36' * 64 opad = b'\x5c' * 64 h_inner = sha256(xor(padded_K, ipad)) h_inner.update(data) h_outer = sha256(xor(padded_K, opad)) h_outer.update(h_inner.digest()) return h_outer.digest()
def __init__(self, key, msg=None): """Create a new HMAC object. key: key for the keyed hash object. msg: Initial input for the hash, if provided. Note: key and msg must be a bytes or bytearray objects. """ if not isinstance(key, (bytes, bytearray)): raise TypeError( "key: expected bytes or bytearray, but got %r" % type(key).__name__ ) self.digest_cons = lambda d=b"": _hashlib.sha256(d) self.outer = self.digest_cons() self.inner = self.digest_cons() blocksize = self.blocksize if len(key) > blocksize: key = self.digest_cons(key).digest() key = key + bytes(blocksize - len(key)) self.outer.update(translate(key, trans_5C)) self.inner.update(translate(key, trans_36)) if msg is not None: self.update(msg)
def encode_key(cls, prevout): # hash up the txid and output number, truncate, and encode as base64 # - truncating at (mod3) bytes so no padding on b64 output # - expects a COutPoint md = sha256('OutptValueCache') md.update(prevout.serialize()) return b2a_base64(md.digest()[:15])[:-1].decode()
def __init__(self): self.part = Partition(Partition.RUNNING).get_next_update() self.sha = hashlib.sha256() self.seq = 0 self.block = 0 self.buf = bytearray(BLOCKLEN) self.buflen = 0
def load_nonce(self, mhash=None): "Set TempKey to a known, but randomly-based value" if mhash != None: # load with known value; won't work with some commands (ReqRandom=1) assert len(mhash) == 32 rv = self.ae_cmd1(opcode=OP.Nonce, p1=3, p2=0, body=mhash) if rv: raise ChipErrorResponse(hex(rv)) else: # A random number must be involved, so no choice in args to OP.Nonce here (ReqRandom). ch2 = random_bytes(20) rndout = self.ae_cmd(opcode=OP.Nonce, p1=0, p2=0, resp_len=32, body=ch2) # NOTE: response is the (old) contents of the RNG, not the TempKey value itself. assert len(rndout) == 32 # TempKey on the chip will be set to the output of SHA256 over # a message composed of my challenge, the RNG and 3 bytes of constants: return sha256(bytes(rndout) + ch2 + b'\x16\0\0').digest()
def do_checkmac(self, slot_num, hkey): "verify we know the SHA256 key in slot n" assert len(hkey) == 32 # Note: cannot read back while data zone is unlocked, but we # can use the key right away in a CheckMac operation and that verifies # it real good. challenge = self.load_nonce() # 32 bytes of "client challenge" and 13 bytes of "other data" are needed, but # we have control over their contents. ch3 = b'0' * 32 # unused/padding od = random_bytes(13) msg = hkey + challenge + od[0:4] + (b'\0'*8) + od[4:7] + b'\xee' \ + od[7:11] + b'\x01\x23' + od[11:13] assert len(msg) == 32 + 32 + 4 + 8 + 3 + 1 + 4 + 2 + 2 resp = sha256(msg).digest() body = ch3 + resp + od assert len(body) == 32 + 32 + 13 # mode=p1 must be 0x01 ... for AuthKey effect to be applied rv = self.ae_cmd1(opcode=OP.CheckMac, p1=0x1, p2=slot_num, body=body) if rv == 1: raise WrongMacVerify() elif rv: raise ChipErrorResponse(hex(rv)) info = self.get_info() #print("After CheckMac Info = %r" % info) #assert info.TK_Valid == 0, info # zero=consumed, but sometimes 1 if used for copy assert info.AuthKey == slot_num, info assert info.AuthValid == 1, 'AuthValid clear: %r' % info self.reset_watchdog()
def write_encrypted(self, slot_num, write_kn, write_key, new_value): # use our knowledge of slot write_kn, to unlock and do encrypted-write into slot_num assert len(new_value) == 32 assert len(write_key) == 32 assert self.is_data_locked( ), "enc write w/ data unlocked writes garbage" dig = self.gendig_slot(write_kn, write_key) #print("After gendig:\n%r" % self.get_info()) self.reset_watchdog() enc = bytes(a ^ b for a, b in zip(dig, new_value)) args = write_params(slot=slot_num, block=0, offset=0, is_data=True, sz=0x80) #print("WRITE: %r data=%s" % (args, b2a_hex(data[0:32]))) assert len(enc) == 32 # "authorizing mac" is also required to be sent: # SHA-256(TempKey, Opcode, Param1, Param2, SN<8>, SN<0:1>, <25 bytes of zeros>, PlainTextData) msg = (dig + ustruct.pack('<bbH', OP.Write, args['p1'], args['p2']) + b'\xee\x01\x23' + (b'\0' * 25) + new_value) assert len(msg) == 32 + 1 + 1 + 2 + 1 + 2 + 25 + 32 auth_mac = sha256(msg).digest() rv = self.ae_cmd1(body=enc + auth_mac, **args) if rv: raise ChipErrorResponse(hex(rv))
def sendTemp(self): print("Sending temperature...", end="") temp = self.get_temp() random = urandom.getrandbits(32) hash = uhashlib.sha256() hash.update( str(esptempconfig.api_id) + str(random) + str(temp) + esptempconfig.api_key) signature = ubinascii.hexlify(hash.digest()).decode() data = "sensor={}&time={}&temp={}&signature={}".format( esptempconfig.api_id, random, temp, signature) resp = urequests.post( esptempconfig.api_endpoint, headers={'content-type': 'application/x-www-form-urlencoded'}, data=data) if resp.status_code == 200: print("OK") return True else: print("FAILED") print(" Data: {}".format(data)) print(" HTTP-Status: {}".format(resp.status_code)) print(" Response: {}".format(resp.text)) return False
def get_device_id(self): """Get an identifier for the device used in server requests In this case, we return the SHA256 hash of the SIM ICCID prefixed with 'ID:' and then prepend an 'IC' (for ICCID) so the result is e.g. devid = 'IC' + SHA256("ID:12345678901234567890") = IC27c6bb74efe9633181ae95bade7740969df13ef15bca1d72a92aa19fb66d24c9""" try: connection = self.lte.isconnected( ) #save connection state on entry if connection: #we are connected at this point and must pause the data session self.lte.pppsuspend() iccid = self.lte.iccid() if connection: #if there was a connection, resume it self.lte.pppresume() except Exception as e: print("Getting device ID failed:") print(e) return "ICERROR" hasher = None try: hasher = uhashlib.sha256("ID:" + iccid) hashvalue = hasher.digest() except Exception as e: if hasher is not None: hasher.digest( ) #make sure hasher is closed, as only one is allowed at a time by the hardware raise e devid = "IC" + ubinascii.hexlify(hashvalue).decode('utf-8') return devid
def getNextAssertion(): global ks_ctap2 global NEXT_CREDENTIAL_TIMER, REM_GETASSERTION_PARAMETERS global CREDENTIALCOUNTER, NUMBEROFCREDENTIALS global REM_GETASSERTION_PARAMETERS_COMMON, REM_LAST_CMD if not REM_GETASSERTION_PARAMETERS: return CTAP2_ERR_NOT_ALLOWED if REM_LAST_CMD not in(authenticatorGetAssertion, authenticatorGetNextAssertion): return CTAP2_ERR_NOT_ALLOWED if CREDENTIALCOUNTER >= NUMBEROFCREDENTIALS: return CTAP2_ERR_NOT_ALLOWED if ticks_diff(ticks_ms(), NEXT_CREDENTIAL_TIMER) > 30000: return CTAP2_ERR_NOT_ALLOWED d, user_description, credentialID = REM_GETASSERTION_PARAMETERS.pop() rp_id_hash, clientDataHash, FLAGS, useRK = REM_GETASSERTION_PARAMETERS_COMMON # increase signature counter ks_ctap2.COUNTER = (ks_ctap2.COUNTER + 1) % 0x0100000000 cb = ks_ctap2.COUNTER.to_bytes(4, 'big') # authenticator data: https://www.w3.org/TR/webauthn/#table-authData auth_data = rp_id_hash + FLAGS + cb # compute signature s = sha256(auth_data + clientDataHash) # auth_data + client_data_hash h = int.from_bytes(s.digest(), 'big', False) signature = ecdsa_sign(secp256r1, d, h) CREDENTIALCOUNTER += 1 NEXT_CREDENTIAL_TIMER = ticks_ms() ret = {1: {'id': credentialID, 'type': 'public-key'}, 2: auth_data, 3: signature} if useRK is True: ret[4] = user_description return CTAP2_OK + encode(ret)
def check_manifest_signature(self, manifest: str, sig_type: str, sig_data: str) -> bool: if (sig_type == "SIG01_PKCS1_PSS_4096_SHA256"): verifier = PKCS1_PSSVerifier(hasher=uhashlib.sha256) pub_modulus = self.PUB_MOD_RSA_4096 hasher = uhashlib.sha256(manifest) manifest_hash = hasher.digest() return verifier.verify(manifest_hash, sig_data, pub_modulus, modBits=4096) elif (sig_type == "SIG02_PKCS1_PSS_4096_SHA512"): verifier = PKCS1_PSSVerifier(hasher=uhashlib.sha512) pub_modulus = self.PUB_MOD_RSA_4096 hasher = uhashlib.sha512(manifest) manifest_hash = hasher.digest() return verifier.verify(manifest_hash, sig_data, pub_modulus, modBits=4096) else: raise Exception("Unknown signature type: {}".format(sig_type)) raise Exception( "Something is wrong with check_manifest_signature(), you should not have reached this line." )
async def handle_download(self, offset, length, file_number): # let them read from where we store the signed txn # - filenumber can be 0 or 1: uploaded txn, or result from sflash import SF # limiting memory use here, should be MAX_BLK_LEN really length = min(length, MAX_BLK_LEN) assert 0 <= file_number < 2, 'bad fnum' assert 0 <= offset <= MAX_TXN_LEN, "bad offset" assert 1 <= length, 'len' # maintain a running SHA256 over what's sent if offset == 0: self.file_checksum = sha256() pos = (MAX_TXN_LEN * file_number) + offset resp = bytearray(4 + length) resp[0:4] = b'biny' SF.read(pos, memoryview(resp)[4:]) self.file_checksum.update(memoryview(resp)[4:]) return resp
def _auth_server_respond(self, topic, msg): if b'client-auth' in topic: msg_hash = sha256(msg) if (hexlify(msg_hash.digest()) == MODULE_SERIAL_HASH): self._server_trust = True return raise OSError(-1)
def u2f_authenticate(control_byte, req): # https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-raw-message-formats-v1.2-ps-20170411.html#authentication-messages global ks_u2f L = req[64] if L != KEY_HANDLE_LENGTH: return SW_WRONG_DATA if len(req) != 64 + 1 + L: return SW_CONDITIONS_NOT_SATISFIED if control_byte not in (0x03, 0x07, 0x08): return SW_CONDITIONS_NOT_SATISFIED key_handle = dec_key_handle(req[65:], req[32:64]) if key_handle == b'': return SW_WRONG_DATA if control_byte == 0x07: # check-only return SW_CONDITIONS_NOT_SATISFIED user_presemce = b'\x00' if control_byte == 0x03: # enforce-user-presence-and-sign if (up_check() is False): return SW_CONDITIONS_NOT_SATISFIED user_presemce = b'\x01' private_key = int.from_bytes(key_handle[:32], 'big', False) ks_u2f.COUNTER = (ks_u2f.COUNTER + 1) % 0x0100000000 cb = ks_u2f.COUNTER.to_bytes(4, 'big') s = sha256(req[32:64] + user_presemce + cb + req[:32]) h = int.from_bytes(s.digest(), 'big', False) signature = ecdsa_sign(secp256r1, private_key, h) return user_presemce + cb + signature + SW_NO_ERROR
def get_device_id(self): #TODO For Wifi, change this to something like the mac address instead of SIM ICCID """Get an identifier for the device used in server requests In this case, we return the SHA256 hash of the SIM ICCID prefixed with 'ID:' and then prepend an 'IC' (for ICCID) so the result is e.g. devid = 'IC' + SHA256("ID:12345678901234567890") = IC27c6bb74efe9633181ae95bade7740969df13ef15bca1d72a92aa19fb66d24c9""" try: lte = LTE() iccid = lte.iccid() except Exception as e: print("Getting device ID failed:") print(e) return "ICERROR" hasher = None try: hasher = uhashlib.sha256("ID:" + iccid) hashvalue = hasher.digest() except Exception as e: if hasher is not None: hasher.digest( ) #make sure hasher is closed, as only one is allowed at a time by the hardware raise e devid = "IC" + ubinascii.hexlify(hashvalue).decode('utf-8') return devid
def pin_prefix(pin, buf_out): # return 4 bytes (32-bit number) # real thing is nothing like this! from uhashlib import sha256 buf_out[0:4] = sha256(pin).digest()[0:4] return 0
async def add_dice_rolls(count, seed, judge_them): from glob import dis from display import FontTiny, FontLarge md = sha256(seed) pr = PressRelease() # fixed parts of screen dis.clear() y = 38 dis.text(0, y, "Press 1-6 for each dice") y += 13 dis.text(0, y, "roll to mix in.") dis.save() while 1: # Note: cannot scroll this msg because 5=up arrow dis.restore() dis.text(None, 0, '%d rolls' % count, FontLarge) hx = str(b2a_hex(md.digest()), 'ascii') dis.text(0, 20, hx[0:32], FontTiny) dis.text(0, 20 + 7, hx[32:], FontTiny) dis.show() ch = await pr.wait() if ch in '123456': count += 1 dis.restore() dis.text(None, 0, '%d rolls' % count, FontLarge) dis.show() # this is slow enough to see md.update(ch) elif ch == 'x': # Because the change (roll) has already been applied, # only let them abort if it's early still if count < 10 and judge_them: return 0, seed elif ch == 'y': if count < 99 and judge_them: if not count: return 0, seed ok = await ux_confirm('''\ You only provided %d dice rolls, and each roll adds only 2.585 bits of entropy. \ For 128-bit security, which is considered the minimum, you need 50 rolls, and \ for 256-bits of security, 99 rolls.''' % count) if not ok: continue break if count: seed = md.digest() return count, seed
def sha256(filename): JUNK = 256 sha = uhashlib.sha256() with open(filename, 'rb') as f: while True: data = f.read(JUNK) if len(data) == 0: return ubinascii.hexlify(sha.digest()) sha.update(data)
def make_checksum(fileobj): block = bytearray(512) checksum = sha256() while True: block = fileobj.read(512) checksum.update(block) if len(block) < 512: break return (hexlify(checksum.digest()).decode())
def generate(entropy): entbytes = int2bytes(entropy) width_bytes = len(entbytes) width_bits = width_bytes * 8 assert width_bits in range(128, 257, 32) sha = uhashlib.sha256(int2bytes(entropy)).digest() checksum = sha[0:1] final = bytes2int(entbytes + checksum) mnemonic = [((final & (2047 << (x * 11))) >> (x * 11)) for x in range(24)] return list(reversed(mnemonic))
def computeFileHash(theFile): f=open(theFile) theHash = uhashlib.sha256() line = f.readline() while line: theHash.update(line) line = f.readline() theRawHash = theHash.digest() # type is 'bytes' hexHash = ubinascii.hexlify(theRawHash) # still 'bytes', but now in hex return hexHash.decode() # hexHash coverted to a string type
def dump_wirebytes(data): (options, body) = dump_header(data) if len(options) > 0: print('hdr.option=%d bytes' % len(options)) print("hdr.end") h = sha256() h.update(body) dump_tlv(body, CTX_TOPLEVEL, 1) print("pkt.digest= 0x" + str(pycn_lite.lib.hexlify(h.digest()), 'ascii'))
def signing_header(self): # payload_hash payload_hash = ubinascii.hexlify( uhashlib.sha256(self.payload).digest()).decode("utf-8") # separate if self.signed_headers and len(self.signed_headers) > 0: separate = b';' else: separate = 0 # canonical_request_sha256 canonical_request = b"%s\n%s\n%s\n%shost:%s\nx-amz-date:%s\n\n%s%shost;x-amz-date\n%s" % \ (self.method, self.path, self.query, self.canonical_headers, self.host, self.amz_date, self.signed_headers, separate, payload_hash) canonical_request_sha256 = ubinascii.hexlify( uhashlib.sha256(canonical_request).digest()).decode("utf-8") # credential_scope credential_scope = b"%s/%s/%s/aws4_request" % ( self.date_stamp, self.region, self.service_name) # signing_key aws4_key = b"AWS4%s" % (self.secret) k_date = hmac.new(aws4_key, self.date_stamp, digestmod=uhashlib.sha256).digest() k_region = hmac.new(k_date, self.region, digestmod=uhashlib.sha256).digest() k_service = hmac.new(k_region, self.service_name, digestmod=uhashlib.sha256).digest() signing_key = hmac.new(k_service, b'aws4_request', digestmod=uhashlib.sha256).digest() string_to_sign = b"%s\n%s\n%s\n%s" % (b"AWS4-HMAC-SHA256", self.amz_date, credential_scope, canonical_request_sha256) signature = ubinascii.hexlify( hmac.new(signing_key, string_to_sign, digestmod=uhashlib.sha256).digest()).decode("utf-8") authorization_header = b"%s Credential=%s/%s, SignedHeaders=%s%shost;x-amz-date, Signature=%s" % \ (b"AWS4-HMAC-SHA256", self.key, credential_scope, self.signed_headers, separate, signature) return authorization_header
def _authenticate(self, passwd): hashwd = uhashlib.sha256(passwd.encode("utf-8")).digest() with open("/etc/passwd", "rb") as fs: checkwd = fs.read() print("orig: %s vs input: %s" % (checkwd, hashwd)) if checkwd == hashwd: self.authenticated = True return True else: return False
def encode_data_wirebytes(comps, blob): buf = bytearray(ccnx.MAX_CHUNK_SIZE) start = len(buf) start = prepend_blob(buf, start, blob) start = prepend_tl(buf, start, ccnx.CCNX_TLV_M_Payload, len(blob)) start = prepend_name(buf, start, comps) start = prepend_tl(buf, start, ccnx.CCNX_TLV_TL_Object, len(buf) - start) h = sha256() h.update(buf[start:]) hdr = bytearray(b'\x01\x01 \x10\x00\x00\x08') struct.pack_into('>H', hdr, 2, len(buf) - start + len(hdr)) return (hdr + buf[start:], h.digest())
def new_message(path: str, device_id: bytes, value: bytes, action: int, dest=DEST_LOCAL): tim = time.time() key = Key(tim=tim, device_id=device_id) sha = hashlib.sha256() sha.update(path) sha.update(str(tim)) sha.update(device_id) sha.update(str(value)) key.data_id = str(hexlify(sha.digest())[:8], 'utf-8') return Message(path, key.string(), value, action, dest)
def file_hash(fname): try: hasher = uhashlib.sha256() with open(fname, mode="rb") as f: chunk = f.read(512) while chunk: hasher.update(chunk) chunk = f.read(512) return hasher.digest() except Exception as e: print("file_hash", e) return None
def encryption_key(self, salt): # Return a 32-byte derived secret to be used for our own internal encryption purposes # 0x80000000 - 0xCC30 = 2147431376 node = self.derive_path("m/2147431408'/0'") # plan: 0' will be an index for other apps acc = sha256(salt) acc.update(node.privkey()) acc.update(salt) pk = ngu.hash.sha256s(acc.digest()) self.register(pk) return pk
def default_remote_id(): """generate remote id based on machine.unique_id()""" import uhashlib from ustruct import unpack # we compute a hash of board's unique_id, since a boards manufactured # closely together probably share prefix or suffix, and I don't know # which one. we want to avoid accidental remote_id clashes unique_hash = uhashlib.sha256(machine.unique_id()).digest() # and a 4 byte prefix of a sha256 hash is more than enough uint32 = unpack("I", unique_hash[:4])[0] # let's mask it to 26 bits uint26 = uint32 & (2**26 - 1) return uint26
try: import uhashlib as hashlib except ImportError: try: import hashlib except ImportError: # This is neither uPy, nor cPy, so must be uPy with # uhashlib module disabled. print("SKIP") raise SystemExit h = hashlib.sha256() print(h.digest()) h = hashlib.sha256() h.update(b"123") print(h.digest()) h = hashlib.sha256() h.update(b"abcd" * 1000) print(h.digest()) print(hashlib.sha256(b"\xff" * 64).digest()) # 56 bytes is a boundary case in the algorithm print(hashlib.sha256(b"\xff" * 56).digest()) # TODO: running .digest() several times in row is not supported() #h = hashlib.sha256(b'123') #print(h.digest())