def aesCCM(key, key_handle, nonce, data, decrypt=False):
    """
    Function implementing YubiHSM AEAD encrypt/decrypt in software.
    """
    if decrypt:
        (data, saved_mac) = _split_data(data, len(data) - pyhsm.defines.YSM_AEAD_MAC_SIZE)

    nonce = pyhsm.util.input_validate_nonce(nonce, pad = True)
    mac = _cbc_mac(key, key_handle, nonce, len(data))

    counter = _ctr_counter(key_handle, nonce, value = 0)
    ctr_aes = AES.new(key, AES.MODE_CTR, counter = counter.next)
    out = []
    while data:
        (thisblock, data) = _split_data(data, pyhsm.defines.YSM_BLOCK_SIZE)

        # encrypt/decrypt and CBC MAC
        if decrypt:
            aes_out = ctr_aes.decrypt(thisblock)
            mac.update(aes_out)
        else:
            mac.update(thisblock)
            aes_out = ctr_aes.encrypt(thisblock)

        out.append(aes_out)

    # Finalize MAC
    counter.value = 0
    mac.finalize(counter.pack())
    if decrypt:
        if mac.get() != saved_mac:
            raise pyhsm.exception.YHSM_Error('AEAD integrity check failed')
    else:
        out.append(mac.get())
    return ''.join(out)
Function implementing YubiHSM AEAD encrypt/decrypt in software.