Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    hmac on on lopy

    Scheduled Pinned Locked Moved Software Tools
    other
    5 Posts 2 Posters 1.5k Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T Offline
      this.wiederkehr
      last edited by

      Just came upon an issue with the micropython hmac library on pycom modules:

      https://github.com/micropython/micropython-lib/blob/master/hmac/hmac.py

      OSError: only one active hash operation is permitted at a time

      The problem is, that hmac lib does instantiate two hash objects at the same time (last two lines):

              if callable(digestmod):
                  self.digest_cons = digestmod
              elif isinstance(digestmod, str):
                  self.digest_cons = lambda d=b'': _hashlib.new(digestmod, d)
              else:
                  self.digest_cons = lambda d=b'': digestmod.new(d)
      
              self.outer = self.digest_cons()
              self.inner = self.digest_cons()
      

      Anyone already solved that? Otherwise I'll do ... :-)

      1 Reply Last reply Reply Quote 0
      • M Offline
        martijns
        last edited by

        Running into the same problem here. Did you solve it yet? Would appreciate if you could share your solution.

        1 Reply Last reply Reply Quote 0
        • T Offline
          this.wiederkehr
          last edited by this.wiederkehr

          """HMAC (Keyed-Hashing for Message Authentication) Python module.
          Implements the HMAC algorithm as described by RFC 2104.
          """
          
          import hashlib as _hashlib
          
          trans_5C = bytes((x ^ 0x5C) for x in range(256))
          trans_36 = bytes((x ^ 0x36) for x in range(256))
          
          def translate(d, t):
              return bytes(t[x] for x in d)
          
          # The size of the digests returned by HMAC depends on the underlying
          # hashing module used.  Use digest_size from the instance of HMAC instead.
          digest_size = None
          
          
          
          class HMAC:
              """RFC 2104 HMAC class.  Also complies with RFC 4231.
              This supports the API for Cryptographic Hash Functions (PEP 247).
              """
              blocksize = 64  # 512-bit HMAC; can be changed in subclasses.
          
              def __init__(self, key, msg = None, digestmod = None):
                  """Create a new HMAC object.
                  key:       key for the keyed hash object.
                  msg:       Initial input for the hash, if provided.
                  digestmod: A module supporting PEP 247.  *OR*
                             A hashlib constructor returning a new hash object. *OR*
                             A hash name suitable for hashlib.new().
                             Defaults to hashlib.md5.
                             Implicit default to hashlib.md5 is deprecated and will be
                             removed in Python 3.6.
                  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__)
          
                  if digestmod is None:
                      raise Exception("HMAC() without an explicit digestmod argument "
                                     "is deprecated.")
          
                  if callable(digestmod):
                      self.digest_cons = digestmod
                  elif isinstance(digestmod, str):
                      self.digest_cons = lambda d=b'': _hashlib.new(digestmod, d)
                  else:
                      self.digest_cons = lambda d=b'': digestmod.new(d)
          
                  self.inner = self.digest_cons()
                  self.digest_size = 32
                  self.block_size = 64
          
                  if len(key) > self.block_size:
                      raise Exception('key too long')
          
                  key = key + bytes(self.block_size - len(key))
                  self.inner.update(translate(key, trans_36))
                  self.outer_key_translated = translate(key, trans_5C)
                  if msg is not None:
                      self.update(msg)
          
              @property
              def name(self):
                  return "hmac-" + self.inner.name
          
              def update(self, msg):
                  """Update this hashing object with the string msg.
                  """
                  self.inner.update(msg)
          
          
              def digest(self):
                  """Return the hash value of this hashing object.
                  This returns a string containing 8-bit data.  The object is
                  not altered in any way by this function; you can continue
                  updating the object after calling this function.
                  """
                  inner_digest = self.inner.digest()
                  self.outer = self.digest_cons()
                  self.outer.update(self.outer_key_translated)
                  self.outer.update(inner_digest)
                  return self.outer.digest()
          
          
          def new(key, msg = None, digestmod = None):
              """Create a new hashing object and return it.
              key: The starting key for the hash.
              msg: if available, will immediately be hashed into the object's starting
              state.
              You can now feed arbitrary strings into the object using its update()
              method, and can ask for the hash value at any time by calling its digest()
              method.
              """
              return HMAC(key, msg, digestmod)
          
          
          1 Reply Last reply Reply Quote 3
          • T Offline
            this.wiederkehr
            last edited by this.wiederkehr

            This code is 'works for me' not sure about the limitations anymore...

            Update: i think the limitation is that you can call digest only once.

            M 1 Reply Last reply Reply Quote 1
            • M Offline
              martijns @this.wiederkehr
              last edited by

              @this-wiederkehr
              Seems to work perfectly fine. Even calling it multiple times (from REPL at least) works. Thanks alot! Also for the quick response.

              1 Reply Last reply Reply Quote 0

              Hello! It looks like you're interested in this conversation, but you don't have an account yet.

              Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

              With your input, this post could be even better 💗

              Register Login
              • 1 / 1
              • First post
                Last post

              Pycom on Twitter

              Pycom