diff --git a/.travis.yml b/.travis.yml
index f31331641064850c5eaa5cc313fd169b202b1131..2efdf74c43be6371213de2483f33531a53cfcadc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,4 +30,4 @@ script:
   # Now build picotls examples and test
   - cmake .
   - make
-  - ./picoquic_ct -x zero_rtt_retry -x tls_zero_share -x hrr -x request_client_authentication -x bad_client_certificate -x stress
+  - ./picoquic_ct -x zero_rtt_retry -x request_client_authentication -x bad_client_certificate -x stress
diff --git a/UnitTest1/unittest1.cpp b/UnitTest1/unittest1.cpp
index e4ac1509688e38bc7ea22e9bf7a45ec7f48fb808..b209229231d09af33d526dd454b3e4546c0d2b3d 100644
--- a/UnitTest1/unittest1.cpp
+++ b/UnitTest1/unittest1.cpp
@@ -338,9 +338,9 @@ namespace UnitTest1
             Assert::AreEqual(ret, 0);
         }
 
-        TEST_METHOD(test_hrr)
+        TEST_METHOD(test_retry)
         {
-            int ret = tls_api_hrr_test();
+            int ret = tls_api_retry_test();
 
             Assert::AreEqual(ret, 0);
         }
@@ -435,14 +435,14 @@ namespace UnitTest1
 
             Assert::AreEqual(ret, 0);
         }
-
+#if 0
         TEST_METHOD(test_wrong_keyshare)
         {
             int ret = wrong_keyshare_test();
 
             Assert::AreEqual(ret, 0);
         }
-
+#endif
         TEST_METHOD(test_pn_ctr)
         {
             int ret = pn_ctr_test();
@@ -505,13 +505,14 @@ namespace UnitTest1
 
             Assert::AreEqual(ret, 0);
         }
-
+#if 0
         TEST_METHOD(test_wrong_tls_version_test)
         {
             int ret = wrong_tls_version_test();
 
             Assert::AreEqual(ret, 0);
         }
+#endif
 
         TEST_METHOD(test_set_certificate_and_key)
         {
diff --git a/picoquic/logger.c b/picoquic/logger.c
index 8289e21f7bf89ae1802f9f94ca3298c17d6d9110..3d4aae2c774ad449ba42e3b4ce4541ae2d8634a3 100644
--- a/picoquic/logger.c
+++ b/picoquic/logger.c
@@ -149,8 +149,8 @@ char const* picoquic_log_state_name(picoquic_state_enum state)
     case picoquic_state_client_renegotiate: 
         state_name = "client_renegotiate"; 
         break;
-    case picoquic_state_client_hrr_received: 
-        state_name = "client_hrr_received"; 
+    case picoquic_state_client_retry_received: 
+        state_name = "client_retry_received"; 
         break;
     case picoquic_state_client_init_resent: 
         state_name = "client_init_resent"; 
@@ -197,9 +197,6 @@ char const* picoquic_log_state_name(picoquic_state_enum state)
     case picoquic_state_disconnected:
         state_name = "disconnected"; 
         break;
-    case picoquic_state_server_send_hrr: 
-        state_name = "server_send_hrr"; 
-        break;
     default:
         break;
     }
diff --git a/picoquic/packet.c b/picoquic/packet.c
index b35666154625af4786030740c5b9ce6406c9f1e6..66dfa5e3d742e80c86195f3b32bbddb015734686 100644
--- a/picoquic/packet.c
+++ b/picoquic/packet.c
@@ -519,6 +519,30 @@ int picoquic_parse_header_and_decrypt(
                     break;
                 case picoquic_packet_retry:
                     /* packet is not encrypted */
+                    switch (bytes[ph->pn_offset] & 0xC0) {
+                    case 0x00:
+                    case 0x40: /* single byte encoding */
+                        ph->pn = bytes[ph->pn_offset] & 0x7F;
+                        ph->pnmask = 0xFFFFFFFFFFFFFF80ull;
+                        ph->offset = ph->pn_offset + 1;
+                        ph->payload_length -= 1;
+                        break;
+                    case 0x80: /* two byte encoding */
+                        ph->pn = (PICOPARSE_16(&bytes[ph->pn_offset])) & 0x3FFF;
+                        ph->pnmask = 0xFFFFFFFFFFFFC000ull;
+                        ph->offset = ph->pn_offset + 2;
+                        ph->payload_length -= 2;
+                        break;
+                    case 0xC0:
+                        ph->pn = (PICOPARSE_32(&bytes[ph->pn_offset])) & 0x3FFFFFFF;
+                        ph->pnmask = 0xFFFFFFFFC0000000ull;
+                        ph->offset = ph->pn_offset + 4;
+                        ph->payload_length -= 4;
+                        break;
+                    }
+                    ph->pn64 = ph->pn; /* supposedly 0 all the time.. */
+                    decoded_length = ph->payload_length;
+                    break;
                     break;
                 case picoquic_packet_handshake:
                     decoded_length = picoquic_decrypt_packet(*pcnx, bytes, length, ph,
@@ -560,6 +584,30 @@ int picoquic_parse_header_and_decrypt(
                     break;
                 case picoquic_packet_retry:
                     /* packet is not encrypted */
+                    /* This is ugly, but the sequence number is already gone from the editor's copy */
+                    switch (bytes[ph->pn_offset] & 0xC0) {
+                    case 0x00:
+                    case 0x40: /* single byte encoding */
+                        ph->pn = bytes[ph->pn_offset] & 0x7F;
+                        ph->pnmask = 0xFFFFFFFFFFFFFF80ull;
+                        ph->offset = ph->pn_offset + 1;
+                        ph->payload_length -= 1;
+                        break;
+                    case 0x80: /* two byte encoding */
+                        ph->pn = (PICOPARSE_16(&bytes[ph->pn_offset])) & 0x3FFF;
+                        ph->pnmask = 0xFFFFFFFFFFFFC000ull;
+                        ph->offset = ph->pn_offset + 2;
+                        ph->payload_length -= 2;
+                        break;
+                    case 0xC0:
+                        ph->pn = (PICOPARSE_32(&bytes[ph->pn_offset])) & 0x3FFFFFFF;
+                        ph->pnmask = 0xFFFFFFFFC0000000ull;
+                        ph->offset = ph->pn_offset + 4;
+                        ph->payload_length -= 4;
+                        break;
+                    }
+                    ph->pn64 = ph->pn; /* supposedly 0 all the time.. */
+                    decoded_length = ph->payload_length;
                     break;
                 case picoquic_packet_handshake:
                     decoded_length = picoquic_decrypt_packet(*pcnx, bytes, length, ph,
@@ -739,62 +787,54 @@ void picoquic_process_unexpected_cnxid(
 }
 
 /*
- * Queue a stateless reset packet
+ * Queue a stateless retry packet
  */
 
-void picoquic_queue_stateless_reset(picoquic_cnx_t* cnx,
+void picoquic_queue_stateless_retry(picoquic_cnx_t* cnx,
     picoquic_packet_header* ph, struct sockaddr* addr_from,
     struct sockaddr* addr_to,
     unsigned long if_index_to,
-    uint64_t current_time)
+    uint8_t * token,
+    size_t token_length)
 {
     picoquic_stateless_packet_t* sp = picoquic_create_stateless_packet(cnx->quic);
     size_t checksum_length = picoquic_get_checksum_length(cnx, 1);
-    uint8_t cleartext[PICOQUIC_MAX_PACKET_SIZE];
 
     if (sp != NULL) {
-        uint8_t* bytes = cleartext;
+        uint8_t* bytes = sp->bytes;
         uint32_t byte_index = 0;
         size_t data_bytes = 0;
-        size_t ack_bytes = 0;
         uint32_t header_length = 0;
+        uint32_t pn_offset;
+        uint32_t pn_length;
 
         cnx->remote_cnxid = ph->srce_cnx_id;
 
-        byte_index = header_length = picoquic_predict_packet_header_length(cnx, picoquic_packet_retry);
+        byte_index = header_length = picoquic_create_packet_header(cnx, picoquic_packet_retry,
+            0, bytes, &pn_offset, &pn_length);
 
-        /* Draft 11 requires adding an ACK frame */
-        if (picoquic_record_pn_received(cnx, ph->pn64, current_time, picoquic_packet_context_initial) == 0 &&
-            picoquic_prepare_ack_frame(cnx, current_time, 
-                picoquic_packet_context_initial, bytes + byte_index,
-            PICOQUIC_MAX_PACKET_SIZE - byte_index - checksum_length, &ack_bytes) == 0)
-        {
-            byte_index += (uint32_t)ack_bytes;
-        }
+        /* Draft 13 requires adding the ODCID, no frames  */
+        bytes[byte_index++] = cnx->initial_cnxid.id_len;
+        byte_index += picoquic_format_connection_id(bytes + byte_index,
+            PICOQUIC_MAX_PACKET_SIZE - byte_index - checksum_length, cnx->initial_cnxid);
+        byte_index += (uint32_t)data_bytes;
+        memcpy(&bytes[byte_index], token, token_length);
+        byte_index += token_length;
 
-        /* Copy the tls stream data */
-        if (picoquic_prepare_crypto_hs_frame(cnx, 0 /* assume stateless reply in initial state */,
-            bytes + byte_index, PICOQUIC_MAX_PACKET_SIZE - byte_index - checksum_length, &data_bytes)
-            == 0) {
-            uint64_t sequence_number = 0;
+        /* No encryption, but needs to update the payload length */
+        picoquic_update_payload_length(bytes, pn_offset, header_length - pn_length, 
+            byte_index);
+        sp->length = byte_index;
 
-            byte_index += (uint32_t)data_bytes;
-            /* AEAD Encrypt, to the send buffer */
-            sp->length = picoquic_protect_packet(cnx, picoquic_packet_retry, cleartext, sequence_number,
-                byte_index, header_length,
-                sp->bytes, cnx->crypto_context[0].aead_encrypt, cnx->crypto_context[0].pn_enc);
 
-            memset(&sp->addr_to, 0, sizeof(sp->addr_to));
-            memcpy(&sp->addr_to, addr_from,
-                (addr_from->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6));
-            memset(&sp->addr_local, 0, sizeof(sp->addr_local));
-            memcpy(&sp->addr_local, addr_to,
-                (addr_to->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6));
-            sp->if_index_local = if_index_to;
-            picoquic_queue_stateless_packet(cnx->quic, sp);
-        } else {
-            picoquic_delete_stateless_packet(sp);
-        }
+        memset(&sp->addr_to, 0, sizeof(sp->addr_to));
+        memcpy(&sp->addr_to, addr_from,
+            (addr_from->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6));
+        memset(&sp->addr_local, 0, sizeof(sp->addr_local));
+        memcpy(&sp->addr_local, addr_to,
+            (addr_to->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6));
+        sp->if_index_local = if_index_to;
+        picoquic_queue_stateless_packet(cnx->quic, sp);
     }
 }
 
@@ -815,7 +855,39 @@ int picoquic_incoming_initial(
     int ret = 0;
     size_t extra_offset = 0;
 
-    /* TODO: if there is a problem with the retry token, schedule a retry packet */
+    /* Logic to test the retry token.
+     * TODO: this should probably be implemented as a callback */
+    if (cnx->quic->flags&picoquic_context_check_token) {
+        uint8_t * base;
+        size_t len;
+        uint8_t token[16];
+
+        if (addr_from->sa_family == AF_INET) {
+            struct sockaddr_in * a4 = (struct sockaddr_in *)addr_from;
+            len = 4;
+            base = (uint8_t *)&a4->sin_addr;
+        }
+        else {
+            struct sockaddr_in6 * a6 = (struct sockaddr_in6 *)addr_from;
+            len = 16;
+            base = &a6->sin6_addr;
+        }
+
+        if (picoquic_get_retry_token(cnx->quic, base, len,
+            token, sizeof(token)) != 0)
+        {
+            ret = PICOQUIC_ERROR_MEMORY;
+        }
+        else {
+            if (ph->token_length != sizeof(token) ||
+                memcmp(token, bytes + ph->token_offset, sizeof(token)) != 0)
+            {
+                picoquic_queue_stateless_retry(cnx, ph,
+                    addr_from, addr_to, if_index_to, token, sizeof(token));
+                ret = PICOQUIC_ERROR_RETRY;
+            }
+        }
+    }
 
     /* decode the incoming frames */
     if (ret == 0) {
@@ -828,12 +900,6 @@ int picoquic_incoming_initial(
         /* initialization of context & creation of data */
         /* TODO: find path to send data produced by TLS. */
         ret = picoquic_tls_stream_process(cnx);
-
-        /* TODO: remove the stateless reset code, not needed with retry token */
-        if (cnx->cnx_state == picoquic_state_server_send_hrr) {
-            picoquic_queue_stateless_reset(cnx, ph, addr_from, addr_to, if_index_to, current_time);
-            cnx->cnx_state = picoquic_state_disconnected;
-        }
     }
 
     if (ret != 0 || cnx->cnx_state == picoquic_state_disconnected) {
@@ -908,7 +974,7 @@ int picoquic_incoming_retry(
                 if (token == NULL) {
                     ret = PICOQUIC_ERROR_MEMORY;
                 } else {
-                    memcpy(token, &bytes[byte_index], odcil);
+                    memcpy(token, &bytes[byte_index], token_length);
                 }
             }
         }
@@ -925,12 +991,12 @@ int picoquic_incoming_retry(
         cnx->retry_token = token;
         cnx->retry_token_length = token_length;
 
-        picoquic_reset_packet_context(cnx, current_time);
+        picoquic_reset_cnx(cnx, current_time);
     }
 
     if (ret == 0) {
         /* Mark the packet as not required for ack */
-        ret = PICOQUIC_ERROR_HRR;
+        ret = PICOQUIC_ERROR_RETRY;
     }
 
     return ret;
@@ -1324,7 +1390,7 @@ int picoquic_incoming_segment(
         ret = -1;
     } else if (ret == PICOQUIC_ERROR_AEAD_CHECK || ret == PICOQUIC_ERROR_INITIAL_TOO_SHORT ||
         ret == PICOQUIC_ERROR_UNEXPECTED_PACKET || ret == PICOQUIC_ERROR_FNV1A_CHECK || 
-        ret == PICOQUIC_ERROR_CNXID_CHECK || ret == PICOQUIC_ERROR_HRR || ret == PICOQUIC_ERROR_DETECTED ||
+        ret == PICOQUIC_ERROR_CNXID_CHECK || ret == PICOQUIC_ERROR_RETRY || ret == PICOQUIC_ERROR_DETECTED ||
         ret == PICOQUIC_ERROR_CONNECTION_DELETED) {
         /* Bad packets are dropped silently */
 
diff --git a/picoquic/picoquic.h b/picoquic/picoquic.h
index 3f7bdccc9e7110c2a1a70663b59481b05294d675..17c3029d43ad69fcce3b58220060ff00a5017f3e 100644
--- a/picoquic/picoquic.h
+++ b/picoquic/picoquic.h
@@ -58,7 +58,7 @@ extern "C" {
 #define PICOQUIC_ERROR_FRAME_BUFFER_TOO_SMALL (PICOQUIC_ERROR_CLASS + 16)
 #define PICOQUIC_ERROR_INVALID_FRAME (PICOQUIC_ERROR_CLASS + 17)
 #define PICOQUIC_ERROR_CANNOT_CONTROL_STREAM_ZERO (PICOQUIC_ERROR_CLASS + 18)
-#define PICOQUIC_ERROR_HRR (PICOQUIC_ERROR_CLASS + 19)
+#define PICOQUIC_ERROR_RETRY (PICOQUIC_ERROR_CLASS + 19)
 #define PICOQUIC_ERROR_DISCONNECTED (PICOQUIC_ERROR_CLASS + 20)
 #define PICOQUIC_ERROR_DETECTED (PICOQUIC_ERROR_CLASS + 21)
 #define PICOQUIC_ERROR_INVALID_TICKET (PICOQUIC_ERROR_CLASS + 23)
@@ -100,7 +100,7 @@ typedef enum {
     picoquic_state_client_init,
     picoquic_state_client_init_sent,
     picoquic_state_client_renegotiate,
-    picoquic_state_client_hrr_received,
+    picoquic_state_client_retry_received,
     picoquic_state_client_init_resent,
     picoquic_state_server_init,
     picoquic_state_server_handshake,
@@ -115,8 +115,7 @@ typedef enum {
     picoquic_state_closing_received,
     picoquic_state_closing,
     picoquic_state_draining,
-    picoquic_state_disconnected,
-    picoquic_state_server_send_hrr
+    picoquic_state_disconnected
 } picoquic_state_enum;
 
 
@@ -124,7 +123,7 @@ typedef enum {
 * Quic context flags
 */
 typedef enum {
-    picoquic_context_check_cookie = 1,
+    picoquic_context_check_token = 1,
     picoquic_context_unconditional_cnx_id = 2,
     picoquic_context_client_zero_share = 4
 } picoquic_context_flags;
diff --git a/picoquic/quicctx.c b/picoquic/quicctx.c
index 215687bd5dda4990638a257ca075ebdfca02cae2..079588973e8d9f88bed30a880375ffa0d22d9efe 100644
--- a/picoquic/quicctx.c
+++ b/picoquic/quicctx.c
@@ -299,10 +299,10 @@ void picoquic_free(picoquic_quic_t* quic)
 void picoquic_set_cookie_mode(picoquic_quic_t* quic, int cookie_mode)
 {
     if (cookie_mode) {
-        quic->flags |= picoquic_context_check_cookie;
+        quic->flags |= picoquic_context_check_token;
         picoquic_crypto_random(quic, quic->retry_seed, PICOQUIC_RETRY_SECRET_SIZE);
     } else {
-        quic->flags &= ~picoquic_context_check_cookie;
+        quic->flags &= ~picoquic_context_check_token;
     }
 }
 
diff --git a/picoquic/sender.c b/picoquic/sender.c
index e3d30b8595d41c9e9144be142a7d968e3dcdec6f..be153a293dcd160b62a409f360f9a5961da1671e 100644
--- a/picoquic/sender.c
+++ b/picoquic/sender.c
@@ -302,6 +302,7 @@ uint32_t picoquic_create_packet_header(
             length += picoquic_varint_encode(&bytes[length], 16, cnx->retry_token_length);
             if (cnx->retry_token_length > 0) {
                 memcpy(&bytes[length], cnx->retry_token, cnx->retry_token_length);
+                length += cnx->retry_token_length;
             }
         }
     }
@@ -2059,8 +2060,7 @@ int picoquic_prepare_packet(picoquic_cnx_t* cnx, picoquic_packet* packet,
         case picoquic_state_disconnected:
             ret = PICOQUIC_ERROR_DISCONNECTED;
             break;
-        case picoquic_state_client_hrr_received:
-        case picoquic_state_server_send_hrr:
+        case picoquic_state_client_retry_received:
             break;
         default:
             DBG_PRINTF("Unexpected connection state: %d\n", cnx->cnx_state);
diff --git a/picoquic/tls_api.c b/picoquic/tls_api.c
index 2a22696d0b7b67b26a73359eccec53fbc1ad1ca8..dbd327a41bf97e1f999add47594e5a794ca56299 100644
--- a/picoquic/tls_api.c
+++ b/picoquic/tls_api.c
@@ -1032,23 +1032,12 @@ int picoquic_tlscontext_create(picoquic_quic_t* quic, picoquic_cnx_t* cnx, uint6
             }
 
             if (ctx != NULL) {
-                /* Enable server side HRR if cookie mode is required */
-                if ((quic->flags & picoquic_context_check_cookie) != 0) {
-                    /* if the server should enforce the client to do a stateless retry */
-                    ctx->handshake_properties.server.enforce_retry = 1;
-                    ctx->handshake_properties.server.retry_uses_cookie = 1;
-                }
-                else {
-                    /* send cookie and do a stateless retry if cannot find suitable key share */
-                    ctx->handshake_properties.server.retry_uses_cookie = 1;
-                }
-                /* secret used for signing / verifying the cookie(internally uses HMAC) */
-                ctx->handshake_properties.server.cookie.key = cnx->quic->retry_seed;
-                /* additional data to be used for signing / verification */
-                ctx->handshake_properties.server.cookie.additional_data.base
-                    = (uint8_t*)&cnx->path[0]->peer_addr;
-                ctx->handshake_properties.server.cookie.additional_data.len
-                    = cnx->path[0]->peer_addr_len;
+                /* The server should never attempt a stateless retry */
+                ctx->handshake_properties.server.enforce_retry = 0;
+                ctx->handshake_properties.server.retry_uses_cookie = 0;
+                ctx->handshake_properties.server.cookie.key = NULL;
+                ctx->handshake_properties.server.cookie.additional_data.base = NULL;
+                ctx->handshake_properties.server.cookie.additional_data.len = 0;
             }
         }
     }
@@ -1659,7 +1648,7 @@ int picoquic_tls_stream_process(picoquic_cnx_t* cnx)
 
     if (ret == 0) {
         switch (cnx->cnx_state) {
-        case picoquic_state_client_hrr_received:
+        case picoquic_state_client_retry_received:
             /* This is not supposed to happen -- HRR should generate "error in progress" */
             break;
         case picoquic_state_client_init:
@@ -1703,34 +1692,7 @@ int picoquic_tls_stream_process(picoquic_cnx_t* cnx)
         }
     } else if (ret == PTLS_ERROR_IN_PROGRESS && (cnx->cnx_state == picoquic_state_client_init || cnx->cnx_state == picoquic_state_client_init_sent || cnx->cnx_state == picoquic_state_client_init_resent)) {
         /* Extract and install the client 0-RTT key */
-    } else if (ret == PTLS_ERROR_IN_PROGRESS && (cnx->cnx_state == picoquic_state_client_hrr_received)) {
-
-        for (picoquic_packet_context_enum pc = 0;
-            pc < picoquic_nb_packet_context; pc++) {
-            picoquic_packet * next_retrans = cnx->pkt_ctx[pc].retransmit_newest;
-            /* Delete the packets queued for retransmission, but keep the 0-RTT packets */
-            while (next_retrans != NULL) {
-                picoquic_packet * next_next = next_retrans->next_packet;
-                /* TODO: special treatment for EOED packet */
-                if (next_retrans->ptype != picoquic_packet_0rtt_protected) {
-                    picoquic_dequeue_retransmit_packet(cnx, next_retrans, 1);
-                }
-                next_retrans = next_next;
-            }
-        }
-        /* Need to reset the transport state of the connection */
-        cnx->cnx_state = picoquic_state_client_init;
-
-        /* Reset the streams */
-        picoquic_clear_stream(&cnx->tls_stream);
-        cnx->tls_stream.consumed_offset = 0;
-        cnx->tls_stream.stream_flags = 0;
-        cnx->tls_stream.fin_offset = 0;
-        cnx->tls_stream.sent_offset = 0;
-    } else if (ret == PTLS_ERROR_STATELESS_RETRY) {
-        cnx->cnx_state = picoquic_state_server_send_hrr;
-    }
-    else if (ret == PTLS_ERROR_IN_PROGRESS &&
+    } else if (ret == PTLS_ERROR_IN_PROGRESS &&
         (cnx->cnx_state == picoquic_state_server_init ||
             cnx->cnx_state == picoquic_state_server_handshake))
     {
@@ -1813,3 +1775,30 @@ int picoquic_set_tls_key(picoquic_quic_t* quic, const uint8_t* data, size_t len)
 void picoquic_tls_set_client_authentication(picoquic_quic_t* quic, int client_authentication) {
     ((ptls_context_t*)quic->tls_master_ctx)->require_client_authentication = client_authentication;
 }
+
+/*
+ * Check the incoming retry token, or produce a token (place holder)
+ */
+
+int picoquic_get_retry_token(picoquic_quic_t* quic, uint8_t * base, size_t len, 
+    uint8_t * token, uint8_t token_length) {
+    /*Using OpenSSL for now: ptls_hash_algorithm_t ptls_openssl_sha256 */
+    int ret = 0;
+    ptls_hash_algorithm_t* algo = &ptls_openssl_sha256;
+    ptls_hash_context_t* hash_ctx = algo->create();
+    uint8_t final_hash[PTLS_MAX_DIGEST_SIZE];
+
+    if (hash_ctx == NULL || token_length > algo->digest_size ) {
+        ret = -1;
+    } else {
+        hash_ctx->update(hash_ctx, quic->retry_seed, sizeof(quic->retry_seed));
+        if (len > 0) {
+            hash_ctx->update(hash_ctx, base, len);
+        }
+        hash_ctx->update(hash_ctx, &len, sizeof(len));
+        hash_ctx->final(hash_ctx, final_hash, PTLS_HASH_FINAL_MODE_FREE);
+        memcpy(token, final_hash, token_length);
+    }
+
+    return ret;
+}
\ No newline at end of file
diff --git a/picoquic/tls_api.h b/picoquic/tls_api.h
index 5782e515d1e87ae72bc34ef79e812d24276fa9e6..e6d1b3e7f0ffef8d8f1bef4c162504a1b4e71452 100644
--- a/picoquic/tls_api.h
+++ b/picoquic/tls_api.h
@@ -89,4 +89,7 @@ void picoquic_tls_set_client_authentication(picoquic_quic_t* quic, int client_au
 
 int picoquic_does_ticket_allow_early_data(uint8_t* ticket, uint16_t ticket_length);
 
+int picoquic_get_retry_token(picoquic_quic_t* quic, uint8_t * base, size_t len,
+    uint8_t * token, uint8_t token_length);
+
 #endif /* TLS_API_H */
diff --git a/picoquic_t/picoquic_t.c b/picoquic_t/picoquic_t.c
index f5c96f7db4ee0bf9fa137f9c5ca0f1e1bf452a2d..ef011f867f92c29a5503a4c6caa5381e8fe5e14a 100644
--- a/picoquic_t/picoquic_t.c
+++ b/picoquic_t/picoquic_t.c
@@ -83,7 +83,7 @@ static const picoquic_test_def_t test_table[] = {
     { "tls_api_very_long_with_err", tls_api_very_long_with_err_test },
     { "tls_api_very_long_congestion", tls_api_very_long_congestion_test },
     { "http0dot9", http0dot9_test },
-    { "hrr", tls_api_hrr_test },
+    { "retry", tls_api_retry_test },
     { "two_connections", tls_api_two_connections_test },
     { "clear_text_aead", cleartext_aead_test },
     { "multiple_versions", tls_api_multiple_versions_test },
@@ -97,7 +97,9 @@ static const picoquic_test_def_t test_table[] = {
     { "unidir", unidir_test },
     { "mtu_discovery", mtu_discovery_test },
     { "spurious_retransmit", spurious_retransmit_test },
+#if 0
     { "wrong_keyshare", wrong_keyshare_test },
+#endif
     { "pn_ctr", pn_ctr_test},
     { "cleartext_pn_enc", cleartext_pn_enc_test},
     { "pn_enc_1rtt", pn_enc_1rtt_test },
@@ -108,7 +110,9 @@ static const picoquic_test_def_t test_table[] = {
     { "set_verify_certificate_callback_test", set_verify_certificate_callback_test },
     { "virtual_time" , virtual_time_test },
     { "different_params", tls_different_params_test },
+#if 0
     { "wrong_tls_version", wrong_tls_version_test },
+#endif
     { "set_certificate_and_key", set_certificate_and_key_test },
     { "request_client_authentication", request_client_authentication_test },
     { "bad_client_certificate", bad_client_certificate_test },
diff --git a/picoquictest/picoquictest.h b/picoquictest/picoquictest.h
index 9eda575e2542a813cde03b51ba347e0cf4e13369..86f3c22bf602db4c6814bb19bf46b7fdee01d6ed 100644
--- a/picoquictest/picoquictest.h
+++ b/picoquictest/picoquictest.h
@@ -64,7 +64,7 @@ int tls_api_very_long_max_test();
 int tls_api_very_long_with_err_test();
 int tls_api_very_long_congestion_test();
 int http0dot9_test();
-int tls_api_hrr_test();
+int tls_api_retry_test();
 int ackrange_test();
 int ack_of_ack_test();
 int tls_api_two_connections_test();
@@ -85,7 +85,9 @@ int stop_sending_test();
 int unidir_test();
 int mtu_discovery_test();
 int spurious_retransmit_test();
+#if 0
 int wrong_keyshare_test();
+#endif
 int pn_ctr_test();
 int cleartext_pn_enc_test();
 int pn_enc_1rtt_test();
@@ -96,7 +98,9 @@ int bad_certificate_test();
 int set_verify_certificate_callback_test();
 int virtual_time_test();
 int tls_different_params_test();
+#if 0
 int wrong_tls_version_test();
+#endif
 int set_certificate_and_key_test();
 int transport_param_stream_id_test();
 int request_client_authentication_test();
diff --git a/picoquictest/tls_api_test.c b/picoquictest/tls_api_test.c
index 6c67fbc747d5b9064fa718e889dee44ba3b084bd..d1abd1a4e05361235fe0b599a8a40a5f607a0d49 100644
--- a/picoquictest/tls_api_test.c
+++ b/picoquictest/tls_api_test.c
@@ -1395,10 +1395,10 @@ int tls_api_bad_server_reset_test()
 }
 
 /*
- * verify that a connection is correctly established after a stateless redirect
+ * verify that a connection is correctly established after a stateless retry
  */
 
-int tls_api_hrr_test()
+int tls_api_retry_test()
 {
     uint64_t simulated_time = 0;
     uint64_t loss_mask = 0;
@@ -2175,6 +2175,8 @@ int spurious_retransmit_test()
     return ret;
 }
 
+#if 0
+
 /*
  * Test whether the server correctly sends an HRR in response to a 
  * Client Hello proposing an unsupported key share.
@@ -2359,7 +2361,9 @@ int wrong_keyshare_test()
 
     return ret;
 }
+#endif
 
+#if 0
 /*
 * Test whether the server correctly sends an HRR in response to a
 * Client Hello proposing an unsupported key share.
@@ -2499,6 +2503,7 @@ int wrong_tls_version_test()
 
     return ret;
 }
+#endif
 
 /*
 * Set up a connection, and verify