diff --git a/doc/bird.sgml b/doc/bird.sgml
index e2050c13de61dc25dea8da419b935655d94e85c4..5d578b74e4e8ea91a45c3ad1aa8f398edec71168 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -5735,7 +5735,10 @@ protocol rpki [<name>] {
         refresh [keep] <num>;
         retry [keep] <num>;
         expire [keep] <num>;
-        transport tcp;
+        transport tcp {
+                authentication none|md5;
+                password "<text>";
+        };
         transport ssh {
                 bird private key "</path/to/id_rsa>";
                 remote public key "</path/to/known_host>";
@@ -5791,15 +5794,27 @@ specify both channels.
 	instead. This may be useful for implementing loose RPKI check for
 	blackholes. Default: disabled.
 
-        <tag>transport tcp</tag> Unprotected transport over TCP. It's a default
-        transport. Should be used only on secure private networks.
-        Default: tcp
+        <tag>transport tcp { <m/TCP transport options.../ }</tag> Transport over
+        TCP, it's the default transport. Cannot be combined with a SSH transport.
+        Default: TCP, no authentication.
 
         <tag>transport ssh { <m/SSH transport options.../ }</tag> It enables a
         SSHv2 transport encryption. Cannot be combined with a TCP transport.
         Default: off
 </descrip>
 
+<sect3>TCP transport options
+<p>
+<descrip>
+	<tag>authentication none|md5</tag>
+	Select authentication method to be used. <cf/none/ means no
+	authentication, <cf/md5/ is TCP-MD5 authentication (<rfc id="2385">).
+	Default: no authentication.
+
+	<tag>password "<m>text</m>"</tag>
+	Use this password for TCP-MD5 authentication of the RPKI-To-Router session.
+</descrip>
+
 <sect3>SSH transport options
 <p>
 <descrip>
diff --git a/proto/rpki/config.Y b/proto/rpki/config.Y
index 769ebb2c8284bfa07b197f0c89661afe10e8d849..60a4b9f078ce5d8912f7753b69f4acbbf585bf72 100644
--- a/proto/rpki/config.Y
+++ b/proto/rpki/config.Y
@@ -13,6 +13,7 @@ CF_HDR
 CF_DEFINES
 
 #define RPKI_CFG ((struct rpki_config *) this_proto)
+#define RPKI_TR_TCP_CFG ((struct rpki_tr_tcp_config *) RPKI_CFG->tr_config.spec)
 #define RPKI_TR_SSH_CFG ((struct rpki_tr_ssh_config *) RPKI_CFG->tr_config.spec)
 
 static void
@@ -32,7 +33,8 @@ rpki_check_unused_transport(void)
 CF_DECLS
 
 CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER,
-	    RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH, LOCAL, ADDRESS)
+	    RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH, LOCAL, ADDRESS,
+	    AUTHENTICATION, NONE, MD5, PASSWORD)
 
 %type <i> rpki_keep_interval
 
@@ -108,7 +110,7 @@ rpki_cache_addr: text_or_ipa
 };
 
 rpki_transport:
-   TCP rpki_transport_tcp_init
+   TCP rpki_transport_tcp_init rpki_transport_tcp_opts_list rpki_transport_tcp_check
  | SSH rpki_transport_ssh_init '{' rpki_transport_ssh_opts '}' rpki_transport_ssh_check
  ;
 
@@ -119,6 +121,28 @@ rpki_transport_tcp_init:
   RPKI_CFG->tr_config.type = RPKI_TR_TCP;
 };
 
+rpki_transport_tcp_opts_list:
+    /* empty */
+  | '{' rpki_transport_tcp_opts '}'
+  ;
+
+rpki_transport_tcp_opts:
+   /* empty */
+ | rpki_transport_tcp_opts rpki_transport_tcp_item ';'
+ ;
+
+rpki_transport_tcp_item:
+   AUTHENTICATION NONE	{ RPKI_TR_TCP_CFG->auth_type = RPKI_TCP_AUTH_NONE; }
+ | AUTHENTICATION MD5	{ RPKI_TR_TCP_CFG->auth_type = RPKI_TCP_AUTH_MD5; }
+ | PASSWORD text	{ RPKI_TR_TCP_CFG->password = $2; }
+ ;
+
+rpki_transport_tcp_check:
+{
+  if (!RPKI_TR_TCP_CFG->auth_type != !RPKI_TR_TCP_CFG->password)
+    cf_error("Authentication and password options should be used together");
+};
+
 rpki_transport_ssh_init:
 {
 #if HAVE_LIBSSH
diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c
index 4ec48e3ba8928cb794f35c6f156419acaa79e9df..cbd94492d113d80abc79970f9a712da7282bca77 100644
--- a/proto/rpki/rpki.c
+++ b/proto/rpki/rpki.c
@@ -685,6 +685,24 @@ rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, st
     try_reset = 1;
   }
 
+  if (new->tr_config.type == RPKI_TR_TCP)
+  {
+    struct rpki_tr_tcp_config *tcp_old = (void *) old->tr_config.spec;
+    struct rpki_tr_tcp_config *tcp_new = (void *) new->tr_config.spec;
+
+    if (tcp_old->auth_type != tcp_new->auth_type)
+    {
+      CACHE_TRACE(D_EVENTS, cache, "Authentication type changed");
+      return NEED_RESTART;
+    }
+
+    if (bstrcmp(tcp_old->password, tcp_new->password))
+    {
+      CACHE_TRACE(D_EVENTS, cache, "MD5 password changed");
+      return NEED_RESTART;
+    }
+  }
+
 #if HAVE_LIBSSH
   else if (new->tr_config.type == RPKI_TR_SSH)
   {
@@ -842,8 +860,12 @@ rpki_show_proto_info(struct proto *P)
       default_port = RPKI_SSH_PORT;
       break;
 #endif
-    case RPKI_TR_TCP:
-      transport_name = "Unprotected over TCP";
+    case RPKI_TR_TCP:;
+      struct rpki_tr_tcp_config *tcp_cf = (void *) cf->tr_config.spec;
+      if (tcp_cf->auth_type == RPKI_TCP_AUTH_MD5)
+	transport_name = "TCP-MD5";
+      else
+	transport_name = "Unprotected over TCP";
       default_port = RPKI_TCP_PORT;
       break;
     };
diff --git a/proto/rpki/tcp_transport.c b/proto/rpki/tcp_transport.c
index 132f8e2dc90859c96af06477e8c8dd1af1a15489..87451c94e1637fce288d511501b206950d964fbc 100644
--- a/proto/rpki/tcp_transport.c
+++ b/proto/rpki/tcp_transport.c
@@ -24,10 +24,16 @@
 static int
 rpki_tr_tcp_open(struct rpki_tr_sock *tr)
 {
+  struct rpki_cache *cache = tr->cache;
+  struct rpki_config *cf = (void *) cache->p->p.cf;
+  struct rpki_tr_tcp_config *tcp_cf = (void *) cf->tr_config.spec;
   sock *sk = tr->sk;
 
   sk->type = SK_TCP_ACTIVE;
 
+  if (tcp_cf->auth_type == RPKI_TCP_AUTH_MD5)
+    sk->password = tcp_cf->password;
+
   if (sk_open(sk) != 0)
     return RPKI_TR_ERROR;
 
diff --git a/proto/rpki/transport.h b/proto/rpki/transport.h
index bb8d41eb2da1c022b361a2be10525814faf7adf5..10e9acb774e21693807a88c6bfb4cc1ea8a226fa 100644
--- a/proto/rpki/transport.h
+++ b/proto/rpki/transport.h
@@ -56,6 +56,12 @@ enum rpki_tr_type {
 #endif
 };
 
+/* TCP authentication types */
+enum rpki_tcp_auth {
+  RPKI_TCP_AUTH_NONE,
+  RPKI_TCP_AUTH_MD5
+};
+
 /* Common configure structure for transports */
 struct rpki_tr_config {
   enum rpki_tr_type type;		/* RPKI_TR_TCP or RPKI_TR_SSH */
@@ -63,7 +69,8 @@ struct rpki_tr_config {
 };
 
 struct rpki_tr_tcp_config {
-  /* No internal configuration data */
+  enum rpki_tcp_auth auth_type;		/* Authentication type */
+  const char *password;			/* Password used for authentication */
 };
 
 struct rpki_tr_ssh_config {